Ruby has differences between Procs created via Proc.new
and lambda
(or the ->()
operator in 1.9). It appears that non-lambda Procs will splat an array passed in across the block arguments; Procs created via lambda do not.
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)
Does anyone have any insight into the motivations behind this behavior?
Blocks are syntactic structures in Ruby; they are not objects, and cannot be manipulated as objects. It is possible, however, to create an object that represents a block. Depending on how the object is created, it is called a proc or a lambda.
Procs are objects, blocks are notA proc (notice the lowercase p) is an instance of the Proc class. This lets us call methods on it and assign it to variables. Procs can also return themselves. In contrast, a block is just part of the syntax of a method call.
A Proc object is an encapsulation of a block of code, which can be stored in a local variable, passed to a method or another Proc, and can be called. Proc is an essential concept in Ruby and a core of its functional programming features.
Ruby lambdas allow you to encapsulate logic and data in an eminently portable variable. A lambda function can be passed to object methods, stored in data structures, and executed when needed. Lambda functions occupy a sweet spot between normal functions and objects.
There are two main differences between lambdas and non-lambda Proc
s:
Proc
s return from the enclosing method, just like blocks.Proc
s have loose argument checking, just like blocks.Or, in short: lambdas behave like methods, non-lambda Proc
s behave like blocks.
What you are seeing there is an instance of #2. Try it with a block and a method in addition to a non-lambda Proc
and a lambda, and you'll see. (Without this behavior, Hash#each
would be a real PITA to use, since it does yield an array with two-elements, but you pretty much always want to treat it as two arguments.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With