Cover by David Flanagan, Yukihiro Matsumoto

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

O'Reilly logo

Closures

In Ruby, procs and lambdas are closures. The term “closure” comes from the early days of computer science; it refers to an object that is both an invocable function and a variable binding for that function. When you create a proc or a lambda, the resulting Proc object holds not just the executable block but also bindings for all the variables used by the block.

You already know that blocks can use local variables and method arguments that are defined outside the block. In the following code, for example, the block associated with the collect iterator uses the method argument n:

# multiply each element of the data array by n
def multiply(data, n)
  data.collect {|x| x*n }
end

puts multiply([1,2,3], 2)   # Prints 2,4,6

What is more interesting, and possibly even surprising, is that if the block were turned into a proc or lambda, it could access n even after the method to which it is an argument had returned. The following code demonstrates:

# Return a lambda that retains or "closes over" the argument n
def multiplier(n) 
  lambda {|data| data.collect{|x| x*n } }
end
doubler = multiplier(2)     # Get a lambda that knows how to double
puts doubler.call([1,2,3])  # Prints 2,4,6

The multiplier method returns a lambda. Because this lambda is used outside of the scope in which it is defined, we call it a closure; it encapsulates or “closes over” (or just retains) the binding for the method argument n.

Closures and Shared Variables

It is important to understand that a closure does not just retain ...

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required