SHARE:
Uncategorized

Blocks vs. Procs vs. Lambdas: Ruby Closure Showdown

Flatiron School / 17 October 2012

The following is a guest post by Matt Salerno and originally appeared on his blog. Matt is currently a student a The Flatiron School. You can learn more about him here, or follow him on twitter here.

Early on in your quest to learn Ruby, you’re going to encounter ‘blocks’. These little packets of code that can be passed to methods may make you sweat a little at first, but soon enough, passing blocks to Enumerable instance methods like ‘each’ and ‘map’ will be second nature. Then, one day, you’ll encounter (gulp), a ‘proc’, or (bigger gulp), a ‘lambda’, and you’ll question why you ever got into this coding business in the first place. Luckily, you can cast those doubts aside, because despite the intimidating names, procs and lambdas are really just blocks stored as variables. Let’s take a minute to break this love triangle apart and examine the subtle differences between blocks, procs and lambdas.



Blocks

Blocks are packets of code stored between ‘do…end’ or ’{}’. They’re a way of performing an action on a value returned by a method.

The example above returns “This is a block!”. The method ‘my_method’yields to the block, which then executes it’s code.

(It actually returns ‘nil’ because of the puts statement, but we’re going to ignore that in this and future examples)

Procs

A Proc is just a block that is stored in a variable for repeated use. If we store a proc in a variable, we can pass that variable to any method that expects a proc.

If we want to reuse the block of code stored in the my_proc variable, we can simply define another method that takes a proc and pass in my_proc.

Lambdas

Lambdas are very similar to procs, only with a slightly different syntax.

So, lambdas are like procs. In fact, if we run my_lambda.class, we’ll see that it returns ‘Proc’ – that’s right, lambdas are instances of the Proc class. Now pick your jaw up off the floor and let’s go over the differences between the two.

Procs vs. Lambdas

Procs and lambdas behave in slightly different ways with regards to a) argument handling and b) return context. Lambdas, sticklers that they are, are very particular with arguments, and will raise an error if passed less or more arguments than were set when they were defined. Procs, on the other hand, couldn’t give two bits how many arguments you pass them – a proc will set all unused arguments to nil.

So, if you want your reusable block to require specific amount of arguments, you should use a lambda instead of a proc.

The other way procs and lambdas differ is in return context. When a proc encounters a return statement, it will execute the proc and exit the wrapping method. On the other hand, lambdas, ever the anal retentive counterpart to the freewheeling proc, will execute the lambda and then politely continue to run the wrapping method. Let’s take a look at an example.

As you can see, when returning our proc, we exited the wrapping method (hence the absence of an “end”), while in returning our lambda, we executed the lambda code and then continued executing the wrapping method call.

Conclusion

So procs and lambdas are really just two ways of storing blocks in variables for repeated use. Admittedly, our examples were pretty elementary, but blocks, procs and lambdas can be actually be incredibly powerful. When passed to a method call, they can act on dynamically generated variables (!), making them all ‘Closures’, which is a topic way outside the scope of this post. For now, just think of procs and lambdas as the the odd couple spawn of the all mighty block.

(Note: This post was inspired by a short and very informative presentation on the subject available on speakerdeck. Highly recommended for a more in depth look at use cases of procs and lambdas. Many thanks to the author ; )

Contributing to Open Source: A Beginner's Guide (Part 1 of 2) Previous Post Nokogiri: Simple Scrape in 5 Easy Pieces Next Post