22

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?

1
  • 3
    You may already know this, but this works: l = lambda{ |(a,b)| a+b }; l[[1,2]] #=> 3 Commented Jan 26, 2011 at 5:32

1 Answer 1

39

There are two main differences between lambdas and non-lambda Procs:

  1. Just like methods, lambdas return from themselves, whereas non-lambda Procs return from the enclosing method, just like blocks.
  2. Just like methods, lambdas have strict argument checking, whereas non-lambda Procs have loose argument checking, just like blocks.

Or, in short: lambdas behave like methods, non-lambda Procs 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.)

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the quick response. Has#each / #sort was how I came across this in the first place. I ended up using the following syntax to avoid the verbosity of Proc.new: ->((a,b)) { ... }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.