Ben Emson

What is the Difference Between a Proc and a Lambda in Ruby?

The concepts of a Proc and a lambda in Ruby are subtly different and this post aims to try and explain the differences.

Procs and Lambdas

Firstly why do we need Procs and lambdas? In order to answer this you need to understand what a block is in Ruby.

Understanding what a block is?

A block is simply a piece of code, which is usually attached to a method, Proc or lambda. It is important to note that this block of code is NOT an object (yet...), it is code that is defined either within braces {} or within a do end container.

The code in a block is just logic that hasn't been wrapped into an object yet. When this block is passed to a method and that method has a yield statement then Ruby will wrap that block into a special type of object. That type of object is a Proc object. Once the block becomes a Proc Ruby can use it and the block code 'comes alive'.

Therefore we need a Proc object in order to handle blocks. The next question is how does a lambda fit in.

A lambda is a type of Proc object, it is almost completely identical to a Proc apart from two differences. This little code snippet shows that a Proc and a lambda are derived from the same superclass, Proc. Liquid error: No such file or directory - posix_spawnp

This will output: Liquid error: No such file or directory - posix_spawnp

So what are the subtle differences between Proc and lambda?

As mentioned there are two differences, and these differences are :

  1. in how a Proc/lambda assigns arguments, and
  2. in what happens, when a Proc/lambda calls return within a caller method.

Proc, lambda argument assignment

When a lambda is called with more or less than the required number of arguments Ruby will throw an ArgumentError.

However when a Proc is called with more arguments, no error is thrown and the extra values are simply thrown away. When it is called with less arguments these parameters are simply assigned a value of nil.

These two code snippets demonstrate this: Liquid error: No such file or directory - posix_spawnp This will output: Liquid error: No such file or directory - posix_spawnp

Proc and lambda return behaviour

When a lambda returns a value and this lambda is called within a method then method will simply continue it's execution until it itself returns a value.

However when a Proc returns a value and this Proc is called within a method this containing method will be exited WITHOUT any further execution. This is slightly surprising behaviour, and consequently a Proc should be handled with care.

These two code snippets demonstrate this behaviour: Liquid error: No such file or directory - posix_spawnp

This will output the following: Liquid error: No such file or directory - posix_spawnp

Proc return work around

There is however a very simple work around to avoid a Proc from returning out of it's caller method. Simply removed the return statement, because Ruby always returns the last line this last line will be returned automatically. Liquid error: No such file or directory - posix_spawnp

This will output: Liquid error: No such file or directory - posix_spawnp

Conclusion

As you have seen there are only two small differences between a Proc and a lambda but these differences have quite surprising behaviours. Therefore following the Ruby principle of "...least surprise", it is best practice to use lambdas over Procs unless you absolutely need the Proc behaviour.

For more information please see this article: http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Method_Calls

blog comments powered by Disqus