Functions

Ruby Closures

Ruby Closures

Ruby closures capture variables for stateful functions.

What is a Closure?

In Ruby, a closure is a function or a block of code that can capture and retain variables from its surrounding environment. This allows the closure to maintain state across its execution, making it a powerful tool for creating functions with persistence.

Closures are implemented using blocks, procs, and lambdas in Ruby. They can be passed around as objects and executed at a later time, with access to the variables that were in scope when the closure was created.

Creating Closures with Blocks

Blocks are the simplest form of closures in Ruby. They can capture variables from their surrounding context and execute them later. Blocks are often used with iterators or methods like each, map, and select.

Here's an example of a block capturing a variable:

Using Procs and Lambdas as Closures

Procs and lambdas are objects in Ruby that encapsulate blocks, turning them into closures that can be stored in variables and passed as arguments to methods. They are similar but have some differences in behavior, especially regarding arguments and return statements.

Here's how you can define and use a proc as a closure:

Lambdas are similar to procs but have stricter argument checking and different behavior for the return keyword. Here's an example of a lambda:

Closures for Stateful Functions

Closures can be used to maintain state across invocations of a function. This is particularly useful for creating functions that need to remember previous interactions or data.

Consider the following example, which uses a closure to count how many times a function has been called:

In this example, the counter_proc maintains the state of the count variable across multiple calls, demonstrating how closures can capture and hold onto variables for stateful behavior.