2011-09-14 9 views
7

ho scoperto da heckle cheIn che modo foo (& nil) si comporta diversamente da foo (& "not a proc")?

[1, 2, 3].each(&nil) 

non causa gli eventuali errori - semplicemente restituisce un enumeratore.

Al contrario,

[1, 2, 3].each(&"") 

solleva

TypeError: wrong argument type String (expected Proc) 

Inoltre, &nil cause block_given? per restituire false

def block_given_tester 
    if block_given? 
    puts "Block given" 
    else 
    puts "Block not given" 
    end 
end 

block_given_tester(&nil) # => Block not given 

Non è perché NilClass implementa to_proc - ho controllato il RDoc.

riesco a capire il motivo per cui sarebbe bello avere &nil, ma non sono sicuro di come si fa. Questo è solo uno dei modi in cui nil ha un comportamento speciale non condiviso da altri oggetti?

risposta

7

La risposta può essere trovata guardando il codice sorgente di Ruby.

Ruby 1.8:

sguardo alla funzione block_pass nel file eval.c. Si noti che tratta lo nil in particolare dagli oggetti Proc (la macro NIL_P). Se la funzione viene passata a zero, valuta un blocco vuoto (credo) e restituisce. Il codice subito dopo controlla se l'oggetto è un oggetto (la funzione rb_obj_is_proc) e solleva l'eccezione "tipo di argomento errato (Proc previsto") se non lo è.

Rubino 1.9.2:

Guarda il metodo caller_setup_args nel file vm_insnhelper.c. Converte il proc con to_proc solo se non è zero; in caso contrario, la conversione del tipo e la verifica del tipo vengono ignorate.

+0

Suppongo che tu stia guardando uno dei rami 1.8 non uno dei rami 1.9. –

+0

Sì, quello proviene da Ruby 1.8, poiché è il codice che ho a disposizione. Ora sto scaricando il codice per Ruby 1.9.2 per vedere se qualcosa è cambiato. –

+1

Ho modificato la mia risposta per Ruby 1.9.2. –

Problemi correlati