Closures in Ruby: Blocks, Procs and Lambdas
Tags: ruby, programming, beginners, coding
Published: 2018-09-04 13:38:10

---
title: Closures in Ruby: Blocks, Procs and Lambdas
layout: layout_ruby_magic
description: In Ruby Magic we love to dive into the magic behind the things we use every day to understand how they work. In this edition, we’ll explore the differences between blocks, procs and lambdas.
cover_image: https://blog.appsignal.com/images/blog/2018-09/rm-blocks.jpg
tags: ruby, programming, beginners, coding
published: true
canonical_url: https://blog.appsignal.com/2018/09/04/ruby-magic-closures-in-ruby-blocks-procs-and-lambdas.html
---

In Ruby Magic we love to dive into the magic behind the things we use every day to understand how they work. In this edition, we’ll explore the differences between blocks, procs and lambdas.

In programming languages with first-class functions, functions can be stored in variables and passed as arguments to other functions. Functions can even use other functions as their return values.

A closure is a first-class function with an environment. The environment is a mapping to the variables that existed when the closure was created. The closure will retain its access to these variables, even if they’re defined in another scope.

Ruby doesn’t have first-class functions, but it does have closures in the form of blocks, procs and lambdas. Blocks are used for passing blocks of code to methods, and procs and lambda’s allow storing blocks of code in variables.


## Blocks

In Ruby, *blocks* are snippets of code that can be created to be executed later. Blocks are passed to methods that yield them within the `do` and `end` keywords. One of the many examples is the `#each` method, which loops over [enumerable](https://blog.appsignal.com/2018/05/29/ruby-magic-enumerable-and-enumerator.html) objects.

``` ruby
[1,2,3].each do |n|
  puts "#{n}!"
end

[1,2,3].each { |n| puts "#{n}!" } # the one-line equivalent.
```

In this example, a block is passed to the `Array#each` method, which runs the block for each item in the array and prints it to the console.

``` ruby
def each
  i = 0
  while i < size
    yield at(i)
    i += 1
  end
end
```

In this simplified example of `Array#each`, in the `while` loop, `yield` is called to execute the passed block for every item in the array. Note that this method has no arguments, as the block is passed to the method implicitly.

### Implicit Blocks and the `yield` Keyword

In Ruby, methods can take blocks implicitly and explicitly. Implicit block passing works by calling the `yield` keyword in a method. The `yield` keyword is special. It finds and calls a passed block, so you don't have to add the block to the list of arguments the method accepts.

Because Ruby allows implicit block passing, you can call all methods with a block. If it doesn’t call `yield`, the block is ignored.

``` irb
irb> "foo bar baz".split { p "block!" }
=> ["foo", "bar", "baz"]
```

If the called method *does* yield, the passed block is found and called with any arguments that were passed to the `yield` keyword.

``` ruby
def each
  return to_enum(:each) unless block_given?

  i = 0
  while i < size
    yield at(i)
    i += 1
  end
end
```

This example [returns an instance of `Enumerator`](https://blog.appsignal.com/2018/05/29/ruby-magic-enumerable-and-enumerator.html) unless a block is given.

The `yield` and `block_given?` keywords find the block in the current scope. This allows passing blocks implicitly, but prevents the code from accessing the block directly as it's not stored in a variable.

### Explicitly Passing Blocks

We can explicitly accept a block in a method by adding it as an argument using an ampersand parameter (usually called `&block`). Since the block is now explicit, we can use the `#call` method directly on the resulting object instead of relying on `yield`.

The `&block` argument is not a proper argument, so calling this method with anything else than a block will produce an `ArgumentError`.

``` ruby
def each_explicit(&block)
  return to_enum(:each) unless block

  i = 0
  while i < size
    block.call at(i)
    i += 1
  end
end
```

When a block is passed like this and stored in a variable, it is automatically converted to a *proc*.

## Procs

A "proc" is an instance of the `Proc` class, which holds a code block to be executed, and can be stored in a variable. To create a proc, you call `Proc.new` and pass it a block.

``` ruby
proc = Proc.new { |n| puts "#{n}!" }
```

Since a proc can be stored in a variable, it can also be passed to a method just like a normal argument. In that case, we don't use the ampersand, as the proc is passed explicitly.

``` ruby
def run_proc_with_random_number(proc)
  proc.call(random)
end

proc = Proc.new { |n| puts "#{n}!" }
run_proc_with_random_number(proc)
```

Instead of creating a proc and passing that to the method, you can use Ruby’s ampersand parameter syntax that we saw earlier and use a block instead.

```ruby
def run_proc_with_random_number(&proc)
  proc.call(random)
end

run_proc_with_random_number { |n| puts "#{n}!" }
```

Note the added ampersand to the argument in the method. This will convert a passed block to a proc object and store it in a variable in the method scope.

*Tip*: While it's useful to have the proc in the method in some situations, the conversion of a block to a proc produces a performance hit. Whenever possible, use implicit blocks instead.

### `#to_proc`

Symbols, hashes and methods can be converted to procs using their `#to_proc` methods. A frequently seen use of this is passing a proc created from a symbol to a method.

``` ruby
[1,2,3].map(&:to_s)
[1,2,3].map {|i| i.to_s }
[1,2,3].map {|i| i.send(:to_s) }
```

This example shows three equivalent ways of calling `#to_s` on each element of the array. In the first one, a symbol, prefixed with an ampersand, is passed, which automatically converts it to a proc by calling its `#to_proc` method. The last two show what that proc could look like.

``` ruby
class Symbol
  def to_proc
    Proc.new { |i| i.send(self) }
  end
end
```

Although this is a simplified example, the implementation of `Symbol#to_proc` shows what’s happening under the hood. The method returns a proc which takes one argument and sends `self` to it. Since `self` is the symbol in this context, it calls the `Integer#to_s` method.

## Lambdas

Lambdas are essentially procs with some distinguishing factors. They are more like "regular" methods in two ways: they enforce the number of arguments passed when they're called and they use "normal" returns.

When calling a lambda that expects an argument without one, or if you pass an argument to a lambda that doesn't expect it, Ruby throws an `ArgumentError`.

``` irb
irb> lambda (a) { a }.call
ArgumentError: wrong number of arguments (given 0, expected 1)
        from (irb):8:in `block in irb_binding'
        from (irb):8
        from /Users/jeff/.asdf/installs/ruby/2.3.0/bin/irb:11:in `<main>'
```

Also, a lambda treats the return keyword the same way a method does. When calling a proc, the program yields control to the code block in the proc. So, if the proc returns, the current scope returns. If a proc is called inside a function and calls `return`, the function immediately returns as well.

``` ruby
def return_from_proc
  a = Proc.new { return 10 }.call
  puts "This will never be printed."
end
```

This function will yield control to the proc, so when it returns, the function returns. Calling the function in this example will never print the output and return 10.

``` ruby
def return_from_lambda
  a = lambda { return 10 }.call
  puts "The lambda returned #{a}, and this will be printed."
end
```

When using a lambda, it *will* be printed. Calling `return` in the lambda will behave like calling `return` in a method, so the `a` variable is populated with `10` and the line is printed to the console.

## Blocks, procs and lambdas

Now that we’ve gone all the way into both blocks, procs and lambdas, let’s zoom back out and summarize the comparison.

- Blocks are used extensively in Ruby for passing bits of code to functions. By using the `yield` keyword, a block can be implicitly passed without having to convert it to a proc.
- When using parameters prefixed with ampersands, passing a block to a method results in a proc in the method's context. Procs behave like blocks, but they can be stored in a variable.
- Lambdas are procs that behave like methods, meaning they enforce arity and return as methods instead of in their parent scope.

This concludes our look into closures in Ruby. There's more to learn about closures like lexical scopes and bindings, but we'll keep that for a future episode. In the meantime, please let us know what you'd like to read about in a future installment of Ruby Magic, closures or otherwise.