And when would you use one rather than the other?
-
6Here is one good blog on the same http://awaxman11.github.io/blog/2013/08/05/what-is-the-difference-between-a-block/ – Arup Rakshit Dec 01 '13 at 10:05
-
3Here is more detailed answer: http://stackoverflow.com/questions/626/when-to-use-lambda-when-to-use-proc-new – Dan K.K. Feb 23 '14 at 01:18
-
1In addition to jtbandes's answer, there's also a difference in what the `return` statement returns from in `proc` versus `lambda`. – Ken Bloom Nov 16 '09 at 04:44
-
@ArupRakshit - The link is broken now – Zain Arshad Jun 05 '22 at 16:35
8 Answers
One difference is in the way they handle arguments. Creating a proc using proc {}
and Proc.new {}
are equivalent. However, using lambda {}
gives you a proc that checks the number of arguments passed to it. From ri Kernel#lambda
:
Equivalent to Proc.new, except the resulting Proc objects check the number of parameters passed when called.
An example:
p = Proc.new {|a, b| puts a**2+b**2 } # => #<Proc:0x3c7d28@(irb):1>
p.call 1, 2 # => 5
p.call 1 # => NoMethodError: undefined method `**' for nil:NilClass
p.call 1, 2, 3 # => 5
l = lambda {|a, b| puts a**2+b**2 } # => #<Proc:0x15016c@(irb):5 (lambda)>
l.call 1, 2 # => 5
l.call 1 # => ArgumentError: wrong number of arguments (1 for 2)
l.call 1, 2, 3 # => ArgumentError: wrong number of arguments (3 for 2)
In addition, as Ken points out, using return
inside a lambda returns the value of that lambda, but using return
in a proc returns from the enclosing block.
lambda { return :foo }.call # => :foo
return # => LocalJumpError: unexpected return
Proc.new { return :foo }.call # => LocalJumpError: unexpected return
So for most quick uses they're the same, but if you want automatic strict argument checking (which can also sometimes help with debugging), or if you need to use the return
statement to return the value of the proc, use lambda
.
-
14Would it accurate to say that lambdas are very much like methods (check arguments and return will return from them) while procs are very much like blocks (arguments are not checked and a return will return from the containing method or lambda)? – pedz May 04 '14 at 17:28
-
10I've been to God knows how many websites and articles by now and nobody seems to talk about the utility of Procs vs. methods vs. lambdas. Every explanation just provides a hair-splitting detail of how return values, etc., are different, but none on why it matters. For now I have to conclude that this is a design mess in Ruby. – ankush981 Apr 06 '20 at 14:41
-
1@ankush981 I agree that the args strictness could have been uniform (e.g always strict). But the return differences seem to have their place, I can imagine they have their use cases. Why do you determine it's a "design mess"? It's definitely not documented well though. – Joel Blum Mar 20 '22 at 09:38
The real difference between procs and lambdas has everything to do with control flow keywords. I am talking about return
, raise
, break
, redo
, retry
etc. – those control words. Let's say you have a return statement in a proc. When you call your proc, it will not only dump you out of it, but will also return from the enclosing method e.g.:
def my_method
puts "before proc"
my_proc = Proc.new do
puts "inside proc"
return
end
my_proc.call
puts "after proc"
end
my_method
shoaib@shoaib-ubuntu-vm:~/tmp$ ruby a.rb
before proc
inside proc
The final puts
in the method, was never executed, since when we called our proc, the return
within it dumped us out of the method. If, however, we convert our proc to a lambda, we get the following:
def my_method
puts "before proc"
my_proc = lambda do
puts "inside proc"
return
end
my_proc.call
puts "after proc"
end
my_method
shoaib@shoaib-ubuntu-vm:~/tmp$ ruby a.rb
before proc
inside proc
after proc
The return within the lambda only dumps us out of the lambda itself and the enclosing method continues executing. The way control flow keywords are treated within procs and lambdas is the main difference between them

- 51,333
- 10
- 112
- 145

- 1,114
- 1
- 7
- 17
There are only two main differences.
- First, a
lambda
checks the number of arguments passed to it, while aproc
does not. This means that alambda
will throw an error if you pass it the wrong number of arguments, whereas aproc
will ignore unexpected arguments and assignnil
to any that are missing. - Second, when a
lambda
returns, it passes control back to the calling method; when aproc
returns, it does so immediately, without going back to the calling method.
To see how this works, take a look at the code below. Our first method calls a proc
; the second calls a lambda
.
def batman_ironman_proc
victor = Proc.new { return "Batman will win!" }
victor.call
"Iron Man will win!"
end
puts batman_ironman_proc # prints "Batman will win!"
def batman_ironman_lambda
victor = lambda { return "Batman will win!" }
victor.call
"Iron Man will win!"
end
puts batman_ironman_lambda # prints "Iron Man will win!"
See how the proc
says "Batman will win!", this is because it returns immediately, without going back to the batman_ironman_proc method.
Our lambda
, however, goes back into the method after being called, so the method returns the last code it evaluates: "Iron Man will win!"

- 4,532
- 2
- 36
- 61
# Proc Examples
p = Proc.new { |x| puts x*2 }
[1,2,3].each(&p) # The '&' tells ruby to turn the proc into a block
proc = Proc.new { puts "Hello World" }
proc.call
# Lambda Examples
lam = lambda { |x| puts x*2 }
[1,2,3].each(&lam)
lam = lambda { puts "Hello World" }
lam.call
Differences between Procs and Lambdas
Before I get into the differences between procs and lambdas, it is important to mention that they are both Proc objects.
proc = Proc.new { puts "Hello world" }
lam = lambda { puts "Hello World" }
proc.class # returns 'Proc'
lam.class # returns 'Proc'
However, lambdas are a different ‘flavor’ of procs. This slight difference is shown when returning the objects.
proc # returns '#<Proc:0x007f96b1032d30@(irb):75>'
lam # returns '<Proc:0x007f96b1b41938@(irb):76 (lambda)>'
1. Lambdas check the number of arguments, while procs do not
lam = lambda { |x| puts x } # creates a lambda that takes 1 argument
lam.call(2) # prints out 2
lam.call # ArgumentError: wrong number of arguments (0 for 1)
lam.call(1,2,3) # ArgumentError: wrong number of arguments (3 for 1)
In contrast, procs don’t care if they are passed the wrong number of arguments.
proc = Proc.new { |x| puts x } # creates a proc that takes 1 argument
proc.call(2) # prints out 2
proc.call # returns nil
proc.call(1,2,3) # prints out 1 and forgets about the extra arguments
2. Lambdas and procs treat the ‘return’ keyword differently
‘return’ inside of a lambda triggers the code right outside of the lambda code
def lambda_test
lam = lambda { return }
lam.call
puts "Hello world"
end
lambda_test # calling lambda_test prints 'Hello World'
‘return’ inside of a proc triggers the code outside of the method where the proc is being executed
def proc_test
proc = Proc.new { return }
proc.call
puts "Hello world"
end
proc_test # calling proc_test prints nothing
And to answer your other query, which one to use and when ? I'll follow @jtbandes as he has mentioned
So for most quick uses they're the same, but if you want automatic strict argument checking (which can also sometimes help with debugging), or if you need to use the return statement to return the value of the proc, use lambda.
Originally posted here

- 1,312
- 15
- 15
Generally speaking, lambdas are more intuitive than procs because they’re more similar to methods. They’re pretty strict about arity, and they simply exit when you call return . For this reason, many Rubyists use lambdas as a first choice, unless they need the specific features of procs.
Procs: Objects of class Proc
. Like blocks, they are evaluated in the scope
where they’re defined.
Lambdas: Also objects of class Proc
but subtly different from regular procs.
They’re closures like blocks and procs, and as such they’re evaluated in
the scope where they’re defined.
Creating Proc
a = Proc.new { |x| x 2 }
Creating lambda
b = lambda { |x| x 2
}

- 1,206
- 2
- 13
- 21
-
1`a = proc { |x| x 2 }` is the same as `a = Proc.new { |x| x 2 }` – lacostenycoder May 06 '18 at 07:10
Here is another way to understand this.
A block is a chunk of code attached to the invocation to a call of a method on an object. In the below example, self is an instance of an anonymous class inheriting from ActionView::Base in the Rails framework (which itself includes many helper modules). card is a method we call on self. We pass in an argument to the method and then we always attach the block to the end of the method invocation:
self.card :contacts do |c|
// a chunk of valid ruby code
end
Ok, so we are passing a chunk of code to a method. But how do we make use of this block? One option is to convert the chunk of code into an object. Ruby offers three ways to convert a chunk of code into an object
# lambda
> l = lambda { |a| a + 1 }
> l.call(1)
=> 2
# Proc.new
> l2= Proc.new { |a| a + 1 }
> l2.call(1)
=> 2
# & as the last method argument with a local variable name
def add(&block)
end
In the method above, the & converts the block passed to the method into an object and stores that object in the local variable block. In fact, we can show that it has the same behavior as lambda and Proc.new:
def add(&block)
block
end
l3 = add { |a| a + 1 }
l3.call(1)
=> 2
This is IMPORTANT. When you pass a block to a method and convert it using &, the object it creates uses Proc.new to do the conversion.
Note that I avoided the use of "proc" as an option. That's because it Ruby 1.8, it is the same as lambda and in Ruby 1.9, it is the same as Proc.new and in all Ruby versions it should be avoided.
So then you ask what is the difference between lambda and Proc.new?
First, in terms of parameter passing, lambda behaves like a method call. It will raise an exception if you pass the wrong number of arguments. In contrast, Proc.new behaves like parallel assignment. All unused arguments get converted into nil:
> l = lambda {|a,b| puts "#{a} + #{b}" }
=> #<Proc:0x007fbffcb47e40@(irb):19 (lambda)>
> l.call(1)
ArgumentError: wrong number of arguments (1 for 2)
> l2 = Proc.new {|a,b| puts "#{a} + #{b}" }
=> #<Proc:0x007fbffcb261a0@(irb):21>
> l2.call(1)
1 +
Second, lambda and Proc.new handle the return keyword differently. When you do a return inside of Proc.new, it actually returns from the enclosing method, that is, the surrounding context. When you return from a lambda block, it just returns from the block, not the enclosing method. Basically, it exits from the call to the block and continues execution with the rest of the enclosing method.
> def add(a,b)
l = Proc.new { return a + b}
l.call
puts "now exiting method"
end
> add(1,1)
=> 2 # NOTICE it never prints the message "now exiting method"
> def add(a,b)
l = lambda { return a + b }
l.call
puts "now exiting method"
end
> add(1,1)
=> now exiting method # NOTICE this time it prints the message "now exiting method"
So why this behavioral difference? The reason is because with Proc.new, we can use iterators inside the context of enclosing methods and draw logical conclusions. Look at this example:
> def print(max)
[1,2,3,4,5].each do |val|
puts val
return if val > max
end
end
> print(3)
1
2
3
4
We expect that when we invoke return inside the iterator, it will return from the enclosing method. Remember the blocks passed to iterators get converted to objects using Proc.new and that is why when we use return, it will exit the enclosing method.
You can think of lambdas as anonymous methods, they isolate individual blocks of code into an object that can be treated like a method. Ultimately, think of a lambda as behaving as an anomyous method and Proc.new behaving as inline code.

- 8,014
- 9
- 67
- 101
A helpful post on ruby guides: blocks, procs & lambdas
Procs return from the current method, while lambdas return from the lambda itself.
Procs don’t care about the correct number of arguments, while lambdas will raise an exception.

- 158
- 2
- 11
the differences between proc and lambda is that proc is just a copy of code with arguments replaced in turn, while lambda is a function like in other languages. (behavior of return, arguments checks)

- 1,034
- 11
- 13