What the Heck are Code Blocks, Procs, Lambdas, and Closures in Ruby?

Sihui Huang
3 min readApr 27, 2017

--

Code blocks and other members in the closure family are something near to many Rubyists’ hearts. They are extremely powerful, flexible, and, when used well, elegant. They are the cornerstones of Ruby’s functional style of programming.

In this post, we will take a look at procs, code blocks, lambdas, and closures in Ruby and explore the differences between them and how to use them.

I was afraid of all these names for a long time. But after taking a really close look at each one of them and their relationships to each other, I realized they were not that scary at all. Instead, I promise you, they are really fun subjects! 😉

Today we will cover the following four fundamentals:

  1. Definitions of Code Block, Proc, Lambda, and Closure
  2. Constructions
  3. Calling a Code Block/Proc/Lambda
  4. Passing and Returning Procs

In Part 2, we will look at:

5. Scopes, Universes, and Lunch Boxes [FUN STUFF]

6. Differences between a Proc and a Lambda

Part 3 is about:

7. Proc <> Code Block Conversion and Ampersand(&) [FUN STUFF]

Here is the meat for today. 😏

1. Definitions

  • A code block is a block of code. Some people also call a code block a block.
  • A proc is an object that contains a code block. It provides a way to save up a code block and execute it later.
  • A lambda is special kind of proc (more on that later).
  • A closure is a function that: 1. can be passed around as a variable and 2. binds to the same scope in which it was created (more on that later). To different extents, code blocks, procs, and lambdas can be seen as closures. Closure is a higher-level concept compared to Code Block, Proc, and Lambda.

Yup, it’s dead simple and straight forward.

2. Constructions

There are two different ways to construct each of them.

  • Code Block: {} OR do end
  • Proc: Proc.new OR proc followed by a code block
  • Lambda: lambda OR -> (stabby lambda) followed by a code block
  • Closure: again, Code blocks, procs, and lambdas can be seen as different forms of closures.

3. Calling a code block/proc/lambda

As we defined earlier, a proc/lambda is no more than an object containing a code block. The purpose of a proc/lambda is to save the code block and execute it later. So calling a proc/lambda is simply executing the code block it has.

How do you call a proc/lambda?

  • You call it.

How do you execute a code block?

  • You yield it.[1]

Let’s first take a look at calling a proc/lambda.

Similar to the way a code block returns the result of its last line of code, a proc/lambda returns the result of the last of code in its code block.

Let’s take a look at yielding a code block.

A code block can be attached to a method.

We can also pass arguments into a code block.

4. Passing and Returning Procs

Since procs are objects, it makes sense that we can pass procs as arguments to methods the same way we do with other objects (arrays, strings, ect).

It shouldn’t be a surprise that we can also return a proc from a method.

Woohoo! Now you have a sense about what code blocks, procs, lambdas, and closures are. I bet you can’t wait to share this TIL with your Ruby-buddies.

With the basics covered, next up is some fun time with Scopes, Universes, and Lunch Boxes!

[1]: You can also call a “block” by converting it to a proc first, which is what we will look at in part 3 of the series. Stay tuned!

Special thanks to Kirill Klimuk for reading early drafts of this post.

--

--