2011-01-25 34 views
21

Ruby ha differenze tra Proc creati tramite Proc.new e lambda (o l'operatore ->() in 1.9). Sembra che i Proc non-lambda divideranno una matrice passata attraverso gli argomenti del blocco; I processi creati tramite lambda no.Differenze tra Proc e Lambda

p = Proc.new { |a,b| a + b} 
p[[1,2]] # => 3 

l = lambda { |a,b| a + b } 
l[[1,2]] # => ArgumentError: wrong number of arguments (1 for 2) 

Qualcuno ha qualche idea delle motivazioni dietro questo comportamento?

+3

Si può già sapere questo, ma questo funziona: 'l = lambda {| (a, b) | a + b}; l [[1,2]] # => 3' – Phrogz

risposta

38

Esistono due principali differenze tra lambda e non lambda Proc s:

  1. Come metodi, lambda ritornano da sé, mentre non lambda Proc s restituito dal metodo racchiude, come blocchi.
  2. Proprio come i metodi, lambda ha un rigoroso controllo degli argomenti, mentre i non-lambda Proc s hanno un controllo di argomento libero, proprio come i blocchi.

Oppure, in breve: lambda si comporta come i metodi, non lambda Proc s si comportano come blocchi.

Quello che vedete è un'istanza di # 2. Provalo con un blocco e un metodo in aggiunta a un lambda Proc e un lambda, e vedrai. (Senza questo comportamento, Hash#each sarebbe un vero e proprio PITA da usare, dal momento che fa resa un array con due elementi, ma è praticamente sempre voglia di trattarlo come due argomenti.)

+1

Grazie per la rapida risposta. Ha # ciascuno/#sort è stato il modo in cui mi sono imbattuto in questo in primo luogo. Ho finito per utilizzare la seguente sintassi per evitare la verbosità di Proc.new: -> ((a, b)) {...} – Brian