What is the difference between Proc and Lambda?
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 .
Procs have
block-like behavior and lambdas have method-like behavior. Both, however, are
instances of class Proc .
Creating &
invoking procs:
p =
Proc.new {|x,y| x+y }
p.call(1,2)
Creating &
invoking Lamdas:
succ =
lambda {|x| x+1} =>Ruby1.8
succ =
->(x){x>0} =>Ruby1.9
succ.call(1)
●
In
a lambda-created proc, the return statement returns only from the proc itself
●
In
a Proc.new-created proc, the return statement is a little more surprising: it
returns control not just from the proc, but
also from the method enclosing the proc!
Differences:
Procs
|
Lambda
|
A proc is the
object form of a block, and it behaves like a block.
Calling a proc is
like yielding to a block.
A proc is like a
block, so if you call a proc that executes a return statement, it attempts
to return from the method that encloses the block that was
converted to the proc.
For Example:
def test
puts "entering method"
p = Proc.new { puts "entering proc"; return }
p.call # Invoking
the proc makes method return
puts "exiting method" # This line is never executed
end
test
break to do the
same thing like return in a proc.
proc handles the
arguments it receives
flexibly:discarding extras, silently adding nil for omitted arguments.
p = Proc.new
{|x,y| print x,y }
p.call(1,2) # prints 1,2
p.call(1) # prints 1, nil
|
A lambda has
slightly
modified behavior and behaves more like a method than a
block.
whereas calling a
lambda is like invoking a method.
A return statement in a lambda returns from the
lambda itself, not from the method that surrounds the creation site of the
lambda:
For Example:
def test
puts "entering method"
p = lambda { puts "entering lambda"; return }
p.call
# Invoking lambda
does not make the method #return
puts "exiting method"
# This line *is* executed now
end
test
break to do the same thing like return in a lambda.
Lambdas are not flexible
in this way; like methods, they must be invoked with precisely
the number of arguments they are declared with:
l = lambda
{|x,y| print x,y }
l.call(1,2)
# This works
l.call(1) #
Wrong number of arguments
|
next statement works the same in a block, proc, or lambda.
redo also works the
same in procs and lambdas.
retry is never
allowed in procs or lambdas: using it always results in a LocalJumpError.
raise behaves the same in blocks, procs, and
lambdas. Exceptions always propagate up the call stack
No comments:
Post a Comment