And when would you use one rather than the other?
-
The only difference is in the way they handle arguments. Creating a proc using
proc {}
andProc.new {}
are equivalent. However, usinglambda {}
gives you a proc that checks the number of arguments passed to it. Fromri 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 usingreturn
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, uselambda
.OscarRyz : +1 For the sample codeJames Thompson : Good article to follow up on this: http://www.robertsosinski.com/2008/12/21/understanding-ruby-blocks-procs-and-lambdas/ -
In addition to jtbandes's answer, there's also a difference in what the
return
statement returns from inproc
versuslambda
.jtbandes : Good point. I added this to my answer.tadman : I also can't wait for something equivalent to "Ruby 3000" to fix this. This distinction is way too subtle. -
It's somewhat subtle. They're both methods that create closures, and both return Proc objects. There's actually a third way as well —
Proc.new
. The difference is in how they behave, and the specifics depend on whether you're using Ruby 1.8 or 1.9 (in fact, there's yet another way to create them in Ruby 1.9). In the general case, the difference isn't something you need to worry about. Only when you're concerned about strictness does it make a difference. This SO question covers the differences pretty well.
0 comments:
Post a Comment