Ruby 1.9 has 4 different ways to deal with closures.
Cue music
Proc
Procs are the weird ones of the bunch. Technically, all of these things I'm going to describe are Procs. By that I mean, if you check the class
, it's a Proc
.
A Proc
is made by using Proc.new
and passing a block, Proc.new { |x| x }
, or by using the proc
keyword, proc { |x| x }
.
A return
from inside exits completely out of the method enclosing the Proc
.
A Proc
doesn't care about the arguments passed. If you define a Proc
with two parameters, and you pass only 1, or possibly 3, it keeps on trucking. In the case of 1 argument, the second parameter will have the value nil
. If you pass extra arguments, they will be ignored and lost.
Block
Blocks are when you pass an anonymous closure to a method:
def my_method
my_other_method(1) do |x, y|
return x + y
end
end
They work exactly like a Proc
. It wouldn't matter how many arguments my_other_method
called yield
with, the block would execute just fine.1 The return
will also return out of my_method
.
Lambda
A lambda
is probably what you deal with most of time. You make them with the lambda
keyword: f = lambda { |x| x + 1 }
. They are a bit different.
Unlike a Proc
, using return
in a lambda
will simply return from the lambda
, pretty much like you'd expect.
Also unlike a Proc
, lambda
likes to whine if you pass an incorrect number of arguments. It will blow up with an ArgumentError
.
Stabby
The stabby is new in Ruby 1.9, and is just syntactic sugar for lambda
. These are equivalent:
f = lambda { |x| x + 1 }
f2 = ->(x) { x + 1 }
What's all this then?
So anyway I wrote some specs, and here they are (or rather their output). If you want to check out the actual specs, or run them for yourself, head on over to Github.
Block | |
should return from the closure | |
should ignore extra arguments | |
should not care if not enough parameters are passed | |
should set unpassed parameters to `nil` | |
should accept *args | |
Lambda | |
should return from the lambda | |
should whine about too many arguments | |
should whine about too few arguments | |
should accept *args | |
should be a lambda | |
Proc | |
should return from the closure | |
should ignore extra arguments | |
should not care if not enough parameters are passed | |
should set unpassed parameters to `nil` | |
should accept *args | |
should not be a lambda | |
should be a proc when `proc` is used | |
Stabby | |
should return from the stabby | |
should whine about too many arguments | |
should whine about too few arguments | |
should accept *args | |
should be a lambda | |
Finished in 0.01227 seconds | |
22 examples, 0 failures |
- The addition won't work too well, but hey.