2013-08-04 12 views
5

So che send accetta una stringa o un simbolo con argomenti mentre instance_eval prende una stringa o un blocco e la loro differenza potrebbe essere evidente ai ricevitori dati.La differenza di rubino tra send e instance_eval?

La mia domanda è che la differenza 'sotto il cappuccio' è per l'esempio di seguito?

1234.send 'to_s'    # '1234' 
1234.instance_eval 'to_s'  # '1234' 

risposta

7

Dal fine manual:

send (simbolo [, args ...]) → obj
send (string [, args ...]) → obj

Invoca il metodo identificato dal simbolo , passandogli eventuali argomenti specificati. [...] Quando il metodo viene identificato da una stringa, la stringa viene convertita in un simbolo.

e per instance_eval:

instance_eval (string [, filename [, lineno]]) → obj
instance_eval {| | block} → obj

Valuta una stringa contenente codice sorgente rubino, o il blocco specificato, nel contesto del ricevitore (obj). Per impostare il contesto, la variabile self è impostato obj mentre il codice è in esecuzione, l'accesso del codice a variabili istanza s ‘obj.

Così send esegue un metodo, mentre instance_eval esegue un blocco di codice arbitrario di (come una stringa o blocco) con self insieme all'oggetto che si sta chiamando instance_eval on.

Nel tuo caso, non c'è molta differenza in quanto la stringa che stai passando a instance_eval è solo un metodo. La differenza principale è che chiunque leggendo il tuo codice (incluso te tra sei mesi) si starà chiedendo perché stai usando instance_eval per chiamare un singolo metodo.

Potreste anche essere interessati a Object#public_send e BasicObject#__send__

+1

Grande, mi sto già chiedendo perché ho avuto un unico metodo per 'instance_eval'. –

5

Qualunque cosa si può fare con send è un sottoinsieme proprio di quello di instance_eval. Vale a dire, l'argomento su send deve essere un singolo metodo (e i suoi argomenti), mentre l'argomento su instance_method è un codice arbitrario. Pertanto, ogni volta che si dispone di send, è possibile riscriverlo con instance_eval, ma non viceversa.

Tuttavia, performancewise, send è molto più veloce di instance_eval poiché non v'è alcuna analisi aggiuntivo richiesto per eseguire send, mentre instance_eval esigenze per analizzare l'intero argomento.

Nel tuo esempio, il risultato sarà lo stesso, ma il primo verrà eseguito più velocemente.

+1

Bel riassunto, e ho ricevuto il bonus sulle prestazioni! –

Problemi correlati