liveBook · Manning

Closure

As explained in The Well-Grounded Rubyist, Fourth Edition

A closure is executable code together with the lexical variables captured from the environment in which it was created.

A closure packages executable code with the local variable bindings that existed when the code was created. In Ruby, a Proc acts as a closure: calling it later still uses its creation context, even when another method has a local variable with the same name. section 14.1.4 section 14.1.5

A closure remembers its own variable

def make_counter n = 0 Proc.new { n += 1 } end c = make_counter d = make_counter puts c.call # 1 puts c.call # 2 puts d.call # 1 puts c.call # 3 Each call to make_counter creates a separate local n. The returned Proc keeps that n alive and updates it whenever the Proc is called, so c and d maintain independent counts. section 14.1.5

Closures clarify several related Ruby behaviors:

  • Resolve a variable from the scope where the Proc was created, not from the method that later calls it. section 14.1.5
  • Preserve local state after the surrounding method returns, allowing later calls to produce new results from that state. section 14.1.5
  • Create independent state whenever the factory method runs again, because each returned Proc captures a different local variable. section 14.1.5
  • Support concise callable behavior such as mapping each string through a method represented by a symbol. section 14.1.4
def make_counter
  n = 0
  return Proc.new { n += 1 }       1
end
c = make_counter      2
puts c.call
puts c.call
d = make_counter     3
puts d.call
puts c.call      4

Trace how make_counter returns a Proc, preserves n, and produces independent counter sequences. section 14.1.5

How The Well-Grounded Rubyist, Fourth Edition covers it

How deep it goes
Explains creation context, scope resolution, preserved bindings, and independent counters through runnable examples.
Examples
Demonstrates captured variables, multiply_by, make_counter, and Symbol#to_proc mapping.
What it assumes
Assumes familiarity with Ruby methods, local variables, blocks, and Proc objects while clarifying scope behavior through examples.
What you can do after
Build closures with Proc.new and use them to retain state across later calls.
How it connects
Connects closures with Proc objects, lexical scope, local variables, methods, and Symbol#to_proc.

Also explained in

Compare how 20 books explain closure →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of The Well-Grounded Rubyist, Fourth Edition. The section links point to the parts of the book it draws on.