That's why I start with explaining the lambda and later compare with the Proc.
A simple lambda:
my_lambda = lambda { puts "A lambda" } my_lambda.callreturns:
A lambdaSure, you can pass a parameter:
my_lambda = lambda { |param| puts "Parameter: #{param}" } my_lambda.call(1)returns:
Parameter: 1And yeah you can also pass more than one parameter like:
my_lambda = lambda { |p1, p2| puts "Parameters: #{p1}, #{p2}" } my_lambda.call(1, 2)returns:
Parameters: 1, 2You also can pass the lambda to a method for some reasons:
def my_function(block) puts "before lambda" block.call puts "after lambda" end my_lambda = lambda { puts "inside lambda" } my_function my_lambdareturns:
before lambda inside lambda after lambdaThough there are not many reasons for passing logic to an object method without using data of that object. You would more often want to "send logic" to an object for dynamically using its data. Then you pass a parameter like:
def my_function(block) number = 0 block.call(number) end my_lambda = lambda { |p| puts "inside lambda: #{p += 1}" } my_function my_lambdareturns:
inside lambda: 1At this point I note an essential property of closures. They automatically carry with them the bindings from the code location where they were created.
word = "Foo" def redefine_word(block) word = "Bar" puts word block.call end redefine_word(lambda { puts word })You really have to take care of the scope, when you send a block to a function. Consider the output:
Bar Foo
The difference between lambda and Proc
There is another exciting detail I want to put the finger on. Control keywords like return, raise, break, redo, retry do NOT have any impact on the further execution. And that's an important difference to Procs. A lambda example:def my_method puts "before lambda" my_lambda = lambda do puts "inside lambda" return end my_lambda.call puts "after lambda" end my_methodreturns:
before lambda inside lambda after lambdaAnd now the same snippet with a Proc:
def my_method puts "before Proc" my_proc = Proc.new do puts "inside Proc" return end my_proc.call puts "after Proc" end my_methodreturns:
before Proc inside ProcBoom! The "return" inside the Proc prevents executing all following logic (line 8 of "my_method"). Good to know, isn't it? Another important difference concerns the parameters of the block. Lambdas are strict:
my_lambda = lambda { |p1, p2| puts "Parameters: #{p1}, #{p2}" } my_lambda.call("One")ends up in an exception:
wrong number of arguments (1 for 2) (ArgumentError)But a Proc is liberal:
my_proc = proc { |p1, p2| puts "Parameters: #{p1} and #{p2}" } my_proc.call("One")returns:
Parameters: One andKeep the differences in mind, when you choose a Proc or a lambda for closuring.
Supported by Ruby 1.9.3
Keine Kommentare:
Kommentar veröffentlichen