0.4 Blocks, Procs, and Lambdas
Lambda vs. Proc
Blocks in Ruby have had a rather complicated history, which means that the terminology gets weird, and there are a small handful of edge-cases that you should be aware of.
I've already mentioned how Proc, Block and Lambda are often used interchangeably in Ruby and this is fine most of the time. Let’s try to understand what each term actually means, and what the differences between them are, if any.
Note: This section only deals with Ruby 1.9.x and does not apply to Ruby 1.8.x.
As you can see, both approaches produce an instance of a
Proc, though the one created using
lambda is clearly distinguished with the word “lambda” in parentheses - an unusual deviation from the norm.
How are these objects different?
A block created with
lambda behaves like a method when you use
return and simply exits the block, handing control back to the calling method.
A block created with
Proc.new behaves like it’s a part of the calling method when
return is used within it, and returns from both the block itself as well as the calling method.
Here’s an example that uses lambdas - the
return within the block hands control back to the method.
Here’s one that uses
Proc.new - the
return within the block exits not just the block itself, but also the surrounding method.
As a consequence,
Proc.new is something that’s hardly ever used to explicitly create blocks because of these surprising return semantics. It is recommended that you avoid using this form unless absolutely necessary.
Let’s summarize all the different ways in which blocks can be created in Ruby that we have learned thus far.
- Implicitly when invoking a method
- Explicitly using the
Kernel#lambda factory method
- Explicitly using
Both (2) and (3) have alternative syntaxes available to make for terser code. Here they are:
-> literal form is a shorter version of
Kernel#lambda. The following two lines produce identical results.
Kernel#proc factory method is identical to
Proc.new. Note that
proc is a method and not a literal form like
-> nor a keyword like
The following two lines produce identical results.
Ok, that’s all for blocks. You may wish to re-visit material on Array enumeration, one of the most common instances of the use of blocks in Ruby.