2011-01-25 18 views
21

Ruby tiene diferencias entre los procesos creados a través de Proc.new y lambda (o el operador ->() en 1.9). Parece que Procs no lambda splat una matriz pasada a través de los argumentos del bloque; Los procs creados a través de lambda no.Diferencias entre Proc y 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) 

¿Alguien tiene alguna idea de las motivaciones detrás de este comportamiento?

+3

posible que ya saben esto, pero esto funciona: 'l = lambda {| (a, b) | a + b}; l [[1,2]] # => 3' – Phrogz

Respuesta

38

Hay dos diferencias principales entre lambdas y nolambda Proc s:

  1. Al igual que métodos, lambdas regresan de sí mismos, mientras que los no-lambda Proc s de retorno del método que encierra, al igual que los bloques.
  2. Al igual que en los métodos, las lambdas tienen una estricta verificación de los argumentos, mientras que las que no son lambda Proc s tienen una comprobación de argumentos sueltos, al igual que los bloques.

O, en resumen: lambdas se comportan como métodos, no lambda Proc s se comportan como bloques.

Lo que está viendo es una instancia de # 2. Pruébalo con un bloque y un método además de un Proc no lambda y un lambda, y ya verás. (Sin este comportamiento, Hash#each habría una verdadera PITA de usar, ya que hace rendimiento de una matriz con-dos elementos, pero casi siempre quieren tratarlo como dos argumentos.)

+1

Gracias por la respuesta rápida. Tengo # cada/# orden fue la forma en que me encontré con esto en primer lugar. Terminé usando la siguiente sintaxis para evitar la verbosidad de Proc.new: -> ((a, b)) {...} – Brian