Reputation: 1152
While starting with Ruby 2.0, I created a small script that worked with the new keyword parameters. While coding this, the behavior of blocks and lambdas surprised me. Below exercises what I had found:
def print_parameters(proc = nil, &block)
p "Block: #{block.parameters}" if proc.nil?
p "Lambda: #{proc.parameters}" unless proc.nil?
end
print_parameters(-> (first, second = 'test') {})
print_parameters(&-> (first, second = 'test') {})
print_parameters {|first, second = 'test'|}
The results are as follows:
"Lambda: [[:req, :first], [:opt, :second]]"
"Block: [[:req, :first], [:opt, :second]]"
"Block: [[:opt, :first], [:opt, :second]]"
Why is it that creating a block does not have required parameters but using a lambda or a block created from a lambda does?
Upvotes: 1
Views: 147
Reputation: 10630
lambdas
behave more like methods in ruby: when you define a method, if parameter is required that when calling that method you have to supply parameters. Blocks behave more like procs
: procs
can declare parameter but they dont require it.
lambda
syntax actually creates proc
with rigid arity. if you where to output classes of both variables you will see that both lambda and blocks are instances of Proc
. proc
s created using lambda syntax will respond true to #lambda?
method. Also check out this SO discussion to understand some other behavioral distinction between lambdas and procs. When to use lambda, when to use Proc.new?
Upvotes: 0
Reputation: 30445
The semantics of blocks in Ruby are designed to make them as useful as possible for iterators, like Integer#times
or Enumerable#each
. Since blocks do not have required parameters, you can do things like:
10.times { puts "Hello!" }
...or:
10.times { |i| puts i }
This is also the reason behind the next
/ return
distinction in Ruby.
Ruby "lambdas" are different; they are not "optimized" for use as "loop bodies" (though you can use them that way if you want). They are stricter about the number of arguments passed, which potentially can help to catch bugs.
Upvotes: 2