Closures and variable binding in Ruby - Time & Space Complexity
When working with closures in Ruby, it's important to understand how the program runs as the input grows.
We want to see how the number of steps changes when closures capture variables and run repeatedly.
Analyze the time complexity of the following code snippet.
def make_multipliers(n)
multipliers = []
n.times do |i|
multipliers << ->(x) { x * i }
end
multipliers
end
multipliers = make_multipliers(5)
multipliers.each { |m| puts m.call(10) }
This code creates a list of closures that multiply by numbers from 0 to n-1, then calls each closure with 10.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Looping n times to create closures and then looping n times to call them.
- How many times: Each loop runs n times, so total operations grow with n.
As n grows, the number of closures created and calls made both increase linearly.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 20 (10 creates + 10 calls) |
| 100 | About 200 (100 creates + 100 calls) |
| 1000 | About 2000 (1000 creates + 1000 calls) |
Pattern observation: The total steps grow roughly twice as fast as n, which is still a straight line growth.
Time Complexity: O(n)
This means the time to run grows directly in proportion to the number of closures created and called.
[X] Wrong: "Closures cause the code to run slower exponentially because they capture variables."
[OK] Correct: Creating closures and calling them still happens in a simple loop, so time grows linearly, not exponentially.
Understanding how closures work with variable binding and their time cost helps you explain your code clearly and reason about performance in real projects.
"What if we called each closure multiple times inside another loop? How would the time complexity change?"