Bird
Raised Fist0
Rubyprogramming~20 mins

Closures and variable binding in Ruby - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Ruby Closure Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this Ruby closure code?

Consider the following Ruby code using closures and variable binding. What will it print?

Ruby
def make_procs
  procs = []
  3.times do |i|
    procs << Proc.new { i }
  end
  procs
end

procs = make_procs
procs.each { |p| puts p.call }
A
3
3
3
B
0
1
2
C
0
0
0
D
1
2
3
Attempts:
2 left
💡 Hint

In Ruby, the block variable i is captured by value in each iteration, so each Proc remembers its own i.

❓ Predict Output
intermediate
2:00remaining
What does this Ruby closure print when variables change after creation?

Look at this Ruby code where a closure captures a variable that changes after the closure is created. What is printed?

Ruby
def counter
  count = 0
  Proc.new { count += 1 }
end

c = counter
puts c.call
puts c.call
count = 100
puts c.call
A
1
2
2
B
1
2
100
C
0
1
2
D
1
2
3
Attempts:
2 left
💡 Hint

The closure captures the local variable count inside the method, not the top-level count.

🔧 Debug
advanced
2:00remaining
Why does this Ruby closure print the same value three times?

Examine this Ruby code. It creates an array of Procs inside a loop, but all Procs print the same value. Why?

Ruby
procs = []
value = 0
3.times do
  procs << Proc.new { value }
  value += 1
end
procs.each { |p| puts p.call }
ABecause all Procs share the same <code>value</code> variable, which ends at 3
BBecause the block variable is not captured correctly
CBecause Procs are executed immediately in the loop
DBecause <code>value</code> is reset inside the loop each time
Attempts:
2 left
💡 Hint

Think about what variable the Proc actually remembers and when it is evaluated.

📝 Syntax
advanced
2:00remaining
Which option correctly creates a closure capturing loop variable in Ruby?

Which of these code snippets correctly creates an array of Procs that each remember a different loop variable value?

A
procs = []
3.times do |i|
  procs &lt;&lt; Proc.new { i }
end
B
procs = []
3.times do |i|
  procs &lt;&lt; Proc.new { i += 1 }
end
C
procs = []
3.times do |i|
  x = i
  procs &lt;&lt; Proc.new { x }
end
D
procs = []
3.times do |i|
  procs &lt;&lt; Proc.new { |x| i }
end
Attempts:
2 left
💡 Hint

Try to create a new variable inside the loop to capture the current value.

🚀 Application
expert
2:00remaining
How many items are in the resulting array after this Ruby closure code runs?

Analyze this Ruby code that uses closures and variable binding. How many elements does the results array contain after execution?

Ruby
def create_procs
  procs = []
  i = 0
  while i < 3 do
    procs << Proc.new { i }
    i += 1
  end
  procs
end

results = create_procs.map(&:call)
A3
B1
C0
DRaises an error
Attempts:
2 left
💡 Hint

Count how many Procs are added to the array inside the loop.

Practice

(1/5)
1. What is a closure in Ruby?
easy
A. A variable that changes its value automatically
B. A method that can only be called once
C. A function that remembers variables from its creation context
D. A class that cannot be inherited

Solution

  1. Step 1: Understand the definition of closure

    A closure is a function or block that keeps access to variables from where it was created, even if called later.
  2. Step 2: Match the definition to options

    A function that remembers variables from its creation context correctly describes this behavior. Other options describe unrelated concepts.
  3. Final Answer:

    A function that remembers variables from its creation context -> Option C
  4. Quick Check:

    Closure = function remembering variables [OK]
Hint: Closures remember variables where they were made [OK]
Common Mistakes:
  • Thinking closures are just methods
  • Confusing closures with classes
  • Believing closures change variable values automatically
2. Which of the following is the correct way to create a closure using a lambda in Ruby?
easy
A. closure = lambda { |x| x * 2 }
B. closure = def(x) x * 2 end
C. closure = function(x) { x * 2 }
D. closure = -> x x * 2

Solution

  1. Step 1: Identify Ruby lambda syntax

    In Ruby, lambdas can be created with lambda { |args| ... } or ->(args) { ... }.
  2. Step 2: Check each option

    closure = lambda { |x| x * 2 } uses lambda { |x| x * 2 }, which is valid. closure = def(x) x * 2 end uses invalid syntax for a lambda. closure = function(x) { x * 2 } uses JavaScript-like syntax. closure = -> x x * 2 misses parentheses in the arrow syntax, which is invalid.
  3. Final Answer:

    closure = lambda { |x| x * 2 } -> Option A
  4. Quick Check:

    Correct lambda syntax = closure = lambda { |x| x * 2 } [OK]
Hint: Use lambda { |args| ... } for Ruby closures [OK]
Common Mistakes:
  • Using JavaScript or Python syntax
  • Omitting parentheses in arrow lambdas
  • Trying to define lambdas with def keyword
3. What will be the output of this Ruby code?
def make_closures
  closures = []
  3.times do |i|
    closures << lambda { i }
  end
  closures
end

closures = make_closures
closures.each { |c| puts c.call }
medium
A. 2 2 2
B. 0 1 2
C. 0 0 0
D. Error: undefined variable i

Solution

  1. Step 1: Understand variable binding in block

    Ruby lambdas capture block variables like i by value in this context, so each lambda remembers its own i value.
  2. Step 2: Evaluate each lambda call

    The loop sets i to 0, 1, 2 sequentially. Each lambda captures the current i value, so outputs are 0, 1, 2 respectively.
  3. Final Answer:

    0 1 2 -> Option B
  4. Quick Check:

    Lambdas capture distinct values per iteration [OK]
Hint: Ruby block vars in closures captured by value per iteration [OK]
Common Mistakes:
  • Thinking lambdas capture shared variable (all 2)
  • Thinking last value is 3 (off-by-one)
  • Expecting error or all zeros
4. Find the error in this Ruby code that tries to create closures:
closures = []
3.times do |i|
  closures << lambda { j }
  j = i
end
closures.each { |c| puts c.call }
medium
A. Variable j is used before assignment inside the lambda
B. Lambda syntax is incorrect
C. times method cannot be used with blocks
D. closures array is not initialized

Solution

  1. Step 1: Identify variable usage inside lambda

    The lambda uses variable j before it is assigned any value in the block, causing an error when called.
  2. Step 2: Understand variable binding timing

    Since j is assigned after lambda creation, the lambda captures j as nil or undefined at call time, causing an error.
  3. Final Answer:

    Variable j is used before assignment inside the lambda -> Option A
  4. Quick Check:

    Use variables after assignment in closures [OK]
Hint: Assign variables before using them in closures [OK]
Common Mistakes:
  • Assuming lambda syntax is wrong
  • Thinking times method is invalid
  • Ignoring variable initialization order
5. How can you modify this Ruby code to create closures that each remember a different value of i even if i changes later?
closures = []
3.times do |i|
  closures << lambda { i }
end
closures.each { |c| puts c.call }
hard
A. Call closures inside the times block
B. Change lambda to proc
C. Use global variable $i instead of i
D. Use a local variable inside the block to capture i: val = i; closures << lambda { val }

Solution

  1. Step 1: Understand variable capture in closures

    Closures capture variables by reference, so if i changes later, all lambdas see the last value.
  2. Step 2: Use a local variable to capture current value

    Assign val = i inside the block, then create lambda using val. This captures the value at that iteration.
  3. Final Answer:

    Use a local variable inside the block to capture i: val = i; closures << lambda { val } -> Option D
  4. Quick Check:

    Capture current value with local variable [OK]
Hint: Assign loop variable to local var inside block for closure [OK]
Common Mistakes:
  • Thinking proc changes variable capture behavior
  • Using global variables which share state
  • Calling closures too early inside loop
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard