Do you know?
I didn’t. And started to get annoyed by using these terms interchangeably and not really knowing the difference.
There are a few. And they are subtle. I don’t think most of us would ever have problems with it but it’s the kind of information you’ll be glad to know when having those weird behaviors in your code on a Friday at 6:01 pm, just before pushing to production.
I guess blocks are the most widely used term in the ruby community and there is little mistake on when to use it:
[1,2,3].each do |x| puts x*2 end
The code between do and end is a block.
What’s important to keep in mind is that Procs behave like blocks whereas lambdas behave like methods. To understand what that means, I highlighted a couple of examples:
- The return keyword
I mentioned Procs behave just like blocks and as such, the return keyword abide to the same rules. This means, for instance, that the latest puts statement on the following code snippet, will never run:
def my_proc(x) p = Proc.new { puts x*2; return } p.call puts "After calling proc" #This never gets called end my_proc(10) >>20
For blocks - and procs-, return means “return from the calling method”, my_proc in this case. That’s why you don’t get to see the output of the puts statement.
On the other hand, in the lambda’s example, we get the opposite behavior:
def my_lambda(x) p = lambda { puts x*2; return } p.call puts "After calling proc" #This time, we reach this point end my_lambda(10) >>20 >>After calling proc
Here, return says “return from the enclosing iterator”, which, in this case, just returns from the block and continnues the execution of the my_lambda method.
- Argument assignment
On to this second difference, procs and lambdas get more interesting when you can call them with arguments. And that’s when another subtle difference between them comes in.
I’ll start again with a proc:
p = Proc.new { |x,y| puts x, y} p.call >>nil >>nil p.call(1) >>1 >>nil p.call(1,2) >>1 >>2 p.call(1,2,3) >>1 >>2 p.call([1,2]) >>1 >>2
See how procs are flexible? They basically won’t complain if you do not provide parameters, provide extra parameters or even send an array as an argument where, as seen in the code above, it unpacks the array and assign its values to the correct variables.
As you’re probably guessing, lambdas behave like methods and are much less flexible:
l = lambda { |x,y| puts x, y} l.call >>ArgumentError: wrong number of arguments (0 for 2) l.call(1) >>ArgumentError: wrong number of arguments (1 for 2) l.call(1,2) >>1 >>2 l.call(1,2,3) >>ArgumentError: wrong number of arguments (3 for 2) l.call([1,2]) >>ArgumentError: wrong number of arguments (1 for 2)
Despite its name, Kernel.proc returns a lambda in Ruby 1.8. This has been fixed in Ruby 1.9. You actually get a Proc back.
- Reference
The Ruby Programming Language - A must have for any Ruby developer.


Good !
very instructive examples!
I didn´t know about the return behavior differecences between proc´s and lambda´s!
I wonder which code you saw to motivate this post…
Leo, very interesting post! However, being the noob I am in Ruby, I’m not ashamed to say that I didn’t get a clue about it
I suppose procs, lambdas and blocks are not intended to the beginner audience?
Actually, although this concept is associated with a functional programming style, it is part of most structures in ruby that you learn from day one. It’s just a matter of getting used to. If you wanna know more, take a look at the reference section at the end of the post. That is a great book to learn about the language. z ya
[...] done my fair amount of Java for many years, among other things - I end up looking for features like blocks, open classes and syntax sugar like automatic generation of attribute accessors. These are hard to [...]