In Ruby 1.8, there are subtle differences between proc/lambda on the one hand, and Proc.new
on the other.
- What are those differences?
- Can you give guidelines on how to decide which one to choose?
- In Ruby 1.9, proc and lambda are different. What's the deal?
I can't say much about the subtle differences. However, I can point out that Ruby 1.9 now allows optional parameters for lambdas and blocks.
Here's the new syntax for the stabby lambdas under 1.9:
Ruby 1.8 didn't have that syntax. Neither did the conventional way of declaring blocks/lambdas support optional args:
Ruby 1.9, however, supports optional arguments even with the old syntax:
If you wanna build Ruby1.9 for Leopard or Linux, check out this article (shameless self promotion).
I am a bit late on this, but there is one great but little known thing about
Proc.new
not mentioned in comments at all. As by documentation:That said,
Proc.new
lets to chain yielding methods:I found this page which shows what the difference between
Proc.new
andlambda
are. According to the page, the only difference is that a lambda is strict about the number of arguments it accepts, whereasProc.new
converts missing arguments tonil
. Here is an example IRB session illustrating the difference:The page also recommends using lambda unless you specifically want the error tolerant behavior. I agree with this sentiment. Using a lambda seems a tad more concise, and with such an insignificant difference, it seems the better choice in the average situation.
As for Ruby 1.9, sorry, I haven't looked into 1.9 yet, but I don't imagine they would change it all that much (don't take my word for it though, it seems you have heard of some changes, so I am probably wrong there).
Short answer: What matters is what
return
does: lambda returns out of itself, and proc returns out of itself AND the function that called it.What is less clear is why you want to use each. lambda is what we expect things should do in a functional programming sense. It is basically an anonymous method with the current scope automatically bound. Of the two, lambda is the one you should probably be using.
Proc, on the other hand, is really useful for implementing the language itself. For example you can implement "if" statements or "for" loops with them. Any return found in the proc will return out of the method that called it, not the just the "if" statement. This is how languages work, how "if" statements work, so my guess is Ruby uses this under the covers and they just exposed it because it seemed powerful.
You would only really need this if you are creating new language constructs like loops, if-else constructs, etc.
A good way to see it is that lambdas are executed in their own scope (as if it was a method call), while Procs may be viewed as executed inline with the calling method, at least that's a good way of deciding wich one to use in each case.
Another important but subtle difference between procs created with
lambda
and procs created withProc.new
is how they handle thereturn
statement:lambda
-created proc, thereturn
statement returns only from the proc itselfProc.new
-created proc, thereturn
statement is a little more surprising: it returns control not just from the proc, but also from the method enclosing the proc!Here's
lambda
-created proc'sreturn
in action. It behaves in a way that you probably expect:Now here's a
Proc.new
-created proc'sreturn
doing the same thing. You're about to see one of those cases where Ruby breaks the much-vaunted Principle of Least Surprise:Thanks to this surprising behavior (as well as less typing), I tend to favor using
lambda
overProc.new
when making procs.