Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Differences between Proc and Lambda

Tags:

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?

like image 601
Brian Avatar asked Jan 25 '11 23:01

Brian


People also ask

What is proc and lambda in Ruby?

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.

What is difference between PROC and block?

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.

Why we use Proc in Ruby?

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.

What is lambda function in Ruby?

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.


1 Answers

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.)

like image 131
Jörg W Mittag Avatar answered Oct 18 '22 08:10

Jörg W Mittag