I've tried reading about procs and lambda's but I have to keep re-reading the definition.
Can someone explain it to me开发者_如何学C in a way that is clear and memorable?
Edited: After reading other good answers here, I offer the following distillation that might save you some re-reading:
(l)ambda -
(L)ocal return
(L)ooks at the arguments
(p)roc -
(P)ops you out of the method when it returns.
(P)ermits different arguments
Einstein said to "... make things as simple as possible, but no simpler." If he had stack overflow, he would have pointed you here:
What are the differences between a proc and lambda?
or here:
What's the difference between a proc and a lambda in Ruby?
hth -
Perry
A few resources:
- When to use lambda, when to use Proc.new?
- Understanding Ruby Blocks, Procs and Lambdas
There's also an entire chapter in the Read Ruby 1.9 book
The way I think about them is that a lambda behaves more like a function and a Proc or block behaves more like a control structure.
I think the best way to understand why the two exist and what the difference is is to understand how each is used. Take this code for example:
def find (elem)
@array.each { |item| return item if item == elem }
return false
end
It's obvious to anyone familiar with Ruby what happens here, but ask yourself what you are returning from when that return
is called. What you expect, and what happens, is that the method itself returns. Even though we are inside a block of code, it is the method returning, not just the block. That is how a Proc behaves, and it's what lets us use an .each
loop and return from it just like we would in an equivalent for
loop.
On the other hand, lambdas are like functions. If you return from inside a lambda, it exits only from the lambda.
def find (elem)
l = lambda { |item| return item if item == elem }
@array.each(&l)
return false
end
Here, the method would always return false due to the final line not being bypassed by a return
call in the lambda. Lambdas are functions and return from themselves, whereas Procs return from the enclosing method.
So, Procs and blocks and return from the method using them (like a loop would), while lambdas (like methods) return from themselves.
Proc
s behave like blocks. Lambdas behave like methods.
I.e. return
inside a Proc
behaves like return
inside a block and argument binding for Proc
s works the same as argument binding for blocks. return
inside a lambda works like return
inside a method and argument binding for lambdas works the same as argument binding for methods.
Note, however, that lambdas are Proc
s, i.e. they are instances of the Proc
class. The difference between them is whether Proc#lambda?
is true
or false
.
Note also that in older versions of Ruby, Kernel#proc
created a lambda and not a Proc
, which was utterly confusing. This has been fixed in modern versions of Ruby, where Kernel#proc
is now equivalent to Proc.new
and thus creates a Proc
.
Kernel#lambda
and the lambda literal syntax (->(x, y) { x + y }
) always create a lambda, Proc.new
always creates a Proc
and Kernel#proc
depends on the Ruby version.
In a Proc:
- A return statement returns out of the calling context -- for instance all the way out of the method or context that calls the Proc, rather than just out of the Proc block.
- It does not throw an exception for a incorrect number of arguments passed
In a lambda:
- A return statement returns control to the calling context -- out of the block but not out of the method.
- It throws an exception if the incorrect number of arguments are given, just like a method would.
Like Jorg W Mittag says, Procs behave like blocks, and lambdas behave like methods.
The way I memorize it is "proc" rhymes with "block".
精彩评论