Code Blocks, Procs, Lambdas, and Closures in Ruby

Sihui Huang
Gusto Engineering
Published in
3 min readApr 26, 2017

Code blocks and other members of 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 series, 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.

This is part 1 of a three-part series.

Part 1 covers 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

Part 2 covers

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

6. Differences between a Proc and a Lambda

Part 3 covers:

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. Sometimes, people simply 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 a 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 straightforward.

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 to 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 to 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 of 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! (Coming soon)

[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.

Originally published at www.sihui.io on April 26, 2017.

--

--