closures

Closures are a powerful feature in programming languages that allow functions or blocks of code to capture and retain references to variables defined in their surrounding context. In Ruby, closures are commonly used with blocks and lambdas, enabling them to access and manipulate variables from their enclosing scope.

Closures in Ruby have the following characteristics:

  1. Capturing Variables: Closures can access variables defined outside their own scope, including variables from the outer scope in which they are defined. This behavior allows them to retain access to those variables even after the outer scope has finished executing.

def outer_method
  x = 10

  inner_method = Proc.new do
    puts x
  end

  inner_method.call
end

outer_method

Output:

10

In this example, the inner_method closure captures the x variable defined in the outer_method scope. Even though outer_method has finished executing, the closure can still access and print the value of x.

  1. Mutable Captured Variables: Closures have access to variables by reference, meaning that changes made to a captured variable inside a closure affect the original variable in the outer scope.

def outer_method
  counter = 0

  increment = Proc.new do
    counter += 1
    puts counter
  end

  increment.call
  increment.call
end

outer_method

Output:

1
2

In this example, the increment closure captures the counter variable from the outer scope. Each time the closure is invoked with increment.call, the counter variable is incremented and printed. The changes made to counter are retained between closure invocations.

  1. Preserving Enclosing Context: Closures preserve the context in which they are defined, even if they are called in a different scope. This allows them to retain references to variables from their original context, even when invoked elsewhere.

def outer_method
  x = "Hello"

  inner_method = Proc.new do
    puts "#{x}, World!"
  end

  inner_method
end

closure = outer_method
closure.call

Output:

Hello, World!

In this example, the inner_method closure is defined within the outer_method and captures the x variable. The closure is then returned from outer_method and stored in the closure variable. When closure.call is invoked, it still has access to the x variable and prints "Hello, World!".

Understanding closures in Ruby is crucial for writing flexible and reusable code, particularly when working with blocks, lambdas, or functional programming concepts. Closures provide a way to encapsulate behavior and manipulate variables from their surrounding context.

During the interview, you can explain closures by highlighting their ability to capture variables, their mutability, and their preservation of the enclosing context. Additionally, provide examples that demonstrate practical use cases where closures enhance the flexibility and expressive power of Ruby code.

Last updated