Define_method for dynamic methods in Ruby - Time & Space Complexity
We want to understand how the time it takes to create dynamic methods changes as we add more methods.
How does the work grow when we define many methods using define_method?
Analyze the time complexity of the following code snippet.
class DynamicMethods
def initialize(names)
names.each do |name|
self.class.define_method(name) do
"Hello from #{name}!"
end
end
end
end
obj = DynamicMethods.new([:greet, :welcome, :hello])
This code creates methods dynamically for each name in the list.
- Primary operation: Looping over the list of names to define methods.
- How many times: Once for each name in the input list.
Each new method requires one step to define it, so the total work grows as we add more names.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 method definitions |
| 100 | 100 method definitions |
| 1000 | 1000 method definitions |
Pattern observation: The work grows directly with the number of methods we create.
Time Complexity: O(n)
This means the time to define methods grows in a straight line with the number of methods.
[X] Wrong: "Defining methods with define_method is instant no matter how many methods."
[OK] Correct: Each method takes some time to create, so more methods mean more total time.
Understanding how dynamic method creation scales helps you write flexible code that stays efficient as it grows.
"What if we defined methods inside a nested loop? How would that affect the time complexity?"
Practice
define_method do in Ruby?Solution
Step 1: Understand the purpose of
define_methoddefine_methodallows creating methods while the program runs, not just when writing code.Step 2: Compare options with
Only Creates a method dynamically during program execution correctly describes dynamic method creation. Other options describe unrelated actions.define_methodbehaviorFinal Answer:
Creates a method dynamically during program execution -> Option AQuick Check:
define_method = dynamic method creation [OK]
- Thinking define_method deletes methods
- Confusing define_method with method calls
- Assuming define_method defines constants
greet dynamically inside a class using define_method?Solution
Step 1: Recall correct
The method name can be a symbol or string, and the method body is given as a block.define_methodsyntaxStep 2: Check each option for syntax correctness
define_method('greet') { puts 'Hello' } uses parentheses and a block correctly. define_method :greet do puts 'Hello' end misses parentheses and block braces, causing syntax error. Options C and D have invalid syntax.Final Answer:
define_method('greet') { puts 'Hello' } -> Option AQuick Check:
define_method syntax = method name + block [OK]
- Omitting parentheses around method name
- Not using a block for method body
- Writing def inside define_method incorrectly
class Person
[:walk, :run].each do |action|
define_method(action) { puts "I can #{action}" }
end
end
p = Person.new
p.walk
p.runSolution
Step 1: Understand the loop and define_method usage
The code loops over[:walk, :run]usingeach do |action|and defines two methods dynamically. Ruby blocks capture the loop variableactionby value for each iteration, so each method captures its ownactionvalue.Step 2: Trace method calls on instance
p.walkprints"I can walk"andp.runprints"I can run"as expected.Final Answer:
I can walk I can run -> Option BQuick Check:
Blocks capture loop variable per iteration [OK]
- Expecting same output for both methods (confuses closure capture)
- Thinking methods are not defined
- Confusing syntax with errors
class Calculator
[:add, :subtract].each do |op|
define_method(op) do |a, b|
if op == :add
a + b
else
a - b
end
end
end
end
calc = Calculator.new
puts calc.add(5, 3)
puts calc.subtract(5, 3)Solution
Step 1: Understand variable capture in blocks
The block usesopinside the method body, butopis from the outer loop and will be the last value (:subtract) when methods run.Step 2: Explain effect on method behavior
Both methods will behave as ifop == :subtract, so add will subtract incorrectly.Final Answer:
The variableopinside the block always refers to the last symbol -> Option CQuick Check:
Block variable capture causes wrong method behavior [OK]
- Assuming op is unique per method
- Ignoring variable capture in closures
- Thinking syntax is wrong
class Calculator
[:add, :subtract].each do |op|
define_method(op) do |a, b|
if op == :add
a + b
else
a - b
end
end
end
endSolution
Step 1: Understand variable capture problem
The variableopis shared in the loop and captured by the block, causing all methods to use the last value.Step 2: Fix by assigning
Assignopto a local variable inside the loopcurrent_op = opinside the loop, then usecurrent_opinsidedefine_methodblock to capture correct value.Final Answer:
Use a local variable inside the loop to captureopvalue before define_method -> Option DQuick Check:
Local variable capture fixes closure bug [OK]
- Trying to pass op as method argument (won't fix closure)
- Replacing define_method with def (loses dynamic behavior)
- Ignoring the variable capture issue
Ready to prove it?
Pass the test and this pattern moves unknown
