And when would you use one rather than the other?
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.
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.
One difference is in the way they handle arguments. Creating a proc using proc {}
and Proc.new {}
are equivalent. However, using lambda {}
gives you a proc that checks the number of arguments passed to it. From ri Kernel#lambda
:
Equivalent to Proc.new, except the resulting Proc objects check the number of parameters passed when called.
An example:
p = Proc.new {|a, b| puts a**2+b**2 } # => #<Proc:0x3c7d28@(irb):1> p.call 1, 2 # => 5 p.call 1 # => NoMethodError: undefined method `**' for nil:NilClass p.call 1, 2, 3 # => 5 l = lambda {|a, b| puts a**2+b**2 } # => #<Proc:0x15016c@(irb):5 (lambda)> l.call 1, 2 # => 5 l.call 1 # => ArgumentError: wrong number of arguments (1 for 2) l.call 1, 2, 3 # => ArgumentError: wrong number of arguments (3 for 2)
In addition, as Ken points out, using return
inside a lambda returns the value of that lambda, but using return
in a proc returns from the enclosing block.
lambda { return :foo }.call # => :foo return # => LocalJumpError: unexpected return Proc.new { return :foo }.call # => LocalJumpError: unexpected return
So for most quick uses they're the same, but if you want automatic strict argument checking (which can also sometimes help with debugging), or if you need to use the return
statement to return the value of the proc, use lambda
.
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