0Pricing
Ruby Academy · Lesson

Closures and Scope

Capturing variables.

Closures and Scope is a free Ruby Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Ruby Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Capturing Variables

A closure is a function that remembers the variables from the place where it was defined, even after that place has finished running. Procs and lambdas are closures.

name = "Ada"
greeter = -> { puts "Hello, #{name}" }
greeter.call

The Variable Travels With It

The closure does not copy the value; it keeps a live reference to the variable. Change the variable later and the closure sees the new value.

count = 0
reader = -> { count }
count = 5
puts reader.call

Closures Can Mutate

Because the reference is live, a closure can also modify the captured variable.

total = 0
adder = ->(n) { total += n }
adder.call(3)
adder.call(7)
puts total

Surviving the Enclosing Method

The captured variable lives on as long as the closure does, even after the method that created it returns.

def counter
  n = 0
  -> { n += 1 }
end
c = counter
puts c.call
puts c.call
puts c.call

Independent States

Each call to the factory method makes a fresh variable, so separate closures keep separate state.

def counter
  n = 0
  -> { n += 1 }
end
a = counter
b = counter
puts a.call
puts a.call
puts b.call

Block Parameters Are Local

Parameters declared in the pipes are local to the block and never leak outside, even if a same-named variable exists.

x = 100
[1, 2, 3].each { |x| }
puts x  # still 100

Block-Local Variables

List extra names after a semicolon in the pipes to force them to be block-local, shielding outer variables from accidental change.

y = "outer"
[1].each { |i; y| y = "inner" }
puts y  # unchanged

Building Configurable Functions

Closures let you bake configuration into a function once and reuse it many times.

def power_of(exp)
  ->(base) { base ** exp }
end
square = power_of(2)
cube = power_of(3)
puts square.call(5)
puts cube.call(2)

Closures in Iteration

A common gotcha: a closure created in a loop captures the variable, not a snapshot. Building closures per-iteration captures each value separately.

funcs = [1, 2, 3].map { |i| -> { i } }
puts funcs.map(&:call).inspect

Encapsulating Private State

Closures can hide state behind functions, an early form of objects. Here the balance is unreachable except through the returned lambdas.

def make_account(start)
  balance = start
  deposit = ->(n) { balance += n }
  show = -> { balance }
  [deposit, show]
end
dep, show = make_account(100)
dep.call(50)
puts show.call

Putting It Together

Closures bind code to its birthplace:

  • They capture live references to surrounding variables.
  • State survives after the enclosing method returns.
  • Each closure keeps its own independent variables.
def tagger(prefix)
  ->(text) { "[#{prefix}] #{text}" }
end
warn = tagger("WARN")
puts warn.call("low disk space")

Quick Check

Test your understanding of closures.

Recap

You learned closures and scope:

  • Procs and lambdas capture surrounding variables by reference.
  • Captured state outlives the enclosing method.
  • Each closure holds independent state.
  • Block parameters stay local; use ; for block-local vars.
def stepper(by)
  pos = 0
  -> { pos += by }
end
s = stepper(5)
puts s.call
puts s.call

Frequently asked questions

Is the “Closures and Scope” lesson free?

Yes — the full text of “Closures and Scope” is free to read here on the web, and the Ruby Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Ruby Academy course, upgrade to CoddyKit PRO.

What will I learn in “Closures and Scope”?

Capturing variables. You practise Ruby Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Ruby Academy?

No prior experience is required. Ruby Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Closures and Scope” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Ruby Academy lesson?

Yes. Every Ruby Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Blocks Recap
  2. Procs
  3. Lambdas
  4. Closures and Scope
← Back to Ruby Academy