Bird
Raised Fist0
Rubyprogramming~10 mins

Closures and variable binding in Ruby - Interactive Code Practice

Choose your learning style10 modes available
Practice - 5 Tasks
Answer the questions below
1fill in blank
easy

Complete the code to create a closure that returns a lambda adding a fixed number.

Ruby
def make_adder(n)
  return ->(x) { x [1] n }
end

add_five = make_adder(5)
puts add_five.call(10)
Drag options to blanks, or click blank then click option'
A+
B-
C*
D/
Attempts:
3 left
💡 Hint
Common Mistakes
Using subtraction or multiplication instead of addition.
Forgetting to use the lambda syntax.
2fill in blank
medium

Complete the code to capture the variable correctly inside the closure.

Ruby
def make_multipliers
  multipliers = []
  3.times do |i|
    multipliers << ->(x) { x * [1] }
  end
  multipliers
end

procs = make_multipliers
puts procs[0].call(2)
Drag options to blanks, or click blank then click option'
A2
B3
Cx
Di
Attempts:
3 left
💡 Hint
Common Mistakes
Using a fixed number instead of the loop variable.
Using the wrong variable name.
3fill in blank
hard

Fix the error in the closure to correctly capture the loop variable value.

Ruby
def make_procs
  procs = []
  3.times do |i|
    val = i
    procs << -> { val [1] 1 }
  end
  procs
end

procs = make_procs
puts procs[1].call
Drag options to blanks, or click blank then click option'
A-
B+
C*
D/
Attempts:
3 left
💡 Hint
Common Mistakes
Using subtraction or multiplication instead of addition.
Not capturing the variable correctly.
4fill in blank
hard

Fill both blanks to create a closure that captures the current loop variable and multiplies it.

Ruby
def make_funcs
  funcs = []
  4.times do |i|
    funcs << ->(x) { (x [1] i) [2] 2 }
  end
  funcs
end

funcs = make_funcs
puts funcs[2].call(3)
Drag options to blanks, or click blank then click option'
A*
B+
C**
D-
Attempts:
3 left
💡 Hint
Common Mistakes
Using multiplication instead of addition.
Using subtraction instead of exponentiation.
5fill in blank
hard

Fill all three blanks to create a closure that filters and transforms a hash based on variable binding.

Ruby
def filter_transform(data)
  result = data.select { |k, v| v [1] 10 }
               .map { |k, v| [k.[2], v [3] 5] }
  result.to_h
end

input = {"a" => 12, "b" => 8, "c" => 15}
output = filter_transform(input)
puts output
Drag options to blanks, or click blank then click option'
A>
Bupcase
C-
D<
Attempts:
3 left
💡 Hint
Common Mistakes
Using less than instead of greater than for filtering.
Not transforming keys or values correctly.

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