Define_method with closures lets you create methods that remember values from their surrounding code. This helps make flexible and reusable methods.
Define_method with closures in Ruby
define_method(:method_name) do |parameters| # method body using parameters and closed-over variables end
define_method creates a method with the given name.
The block passed to define_method can use variables from outside its scope (closures).
greet that remembers the instance variable @name using closure.class Greeter def initialize(name) @name = name end define_method(:greet) do "Hello, #{@name}!" end end
multiply remembers the @factor and multiplies it with the input number.class Multiplier def initialize(factor) @factor = factor end define_method(:multiply) do |number| number * @factor end end
next method remembers and updates the @count variable each time it is called.class Counter def initialize(start) @count = start end define_method(:next) do @count += 1 end end
This program creates a Person class. It defines a method say_hello using define_method that remembers the person's name and returns a greeting.
class Person def initialize(name) @name = name end define_method(:say_hello) do "Hi, my name is #{@name}." end end person = Person.new("Alice") puts person.say_hello
Closures let the method remember variables like @name even after initialization.
Using define_method is useful for dynamic or repetitive method creation.
Be careful with variable scope to avoid unexpected results.
define_method creates methods dynamically with a block.
The block can use variables from outside, forming a closure.
This helps make flexible, reusable methods that remember data.
Practice
define_method do in Ruby?Solution
Step 1: Understand the purpose of
define_methoddefine_methodis used to create methods dynamically at runtime using a block of code.Step 2: Compare with other options
Options B, C, and D describe different actions unrelated todefine_method.Final Answer:
Creates a method dynamically using a block -> Option DQuick Check:
define_methodcreates methods dynamically [OK]
- Thinking define_method calls methods
- Confusing define_method with deleting methods
- Assuming it defines variables
greet using define_method that returns "Hello"?Solution
Step 1: Recall correct
The correct syntax uses a symbol for the method name and a block:define_methodsyntaxdefine_method(:name) { ... }.Step 2: Check each option
def define_method(:greet) "Hello" end usesdefincorrectly. define_method greet { return "Hello" } lacks symbol (greetundefined). define_method(:greet, "Hello") passes string instead of block. B matches correct syntax.Final Answer:
define_method(:greet) { "Hello" } -> Option CQuick Check:
Correct syntax uses symbol and block [OK]
- Using method name without symbol
- Incorrect block syntax
- Using def inside define_method
class Person
def initialize(name)
@name = name
self.class.define_method(:greet) { "Hello, #{@name}!" }
end
end
p = Person.new("Alice")
puts p.greetSolution
Step 1: Understand closure and instance variable scope
The block passed todefine_methoddefines the method body. However, the string interpolation"Hello, #{@name}!"is evaluated immediately whendefine_methodis called, not when the method is invoked. At that time,@nameis nil because the block is defined in the class context, not the instance context.Step 2: Predict output
Therefore, the methodgreetreturns the string with@nameinterpolated as nil, resulting in "Hello, !".Final Answer:
Hello, ! -> Option BQuick Check:
String interpolation in define_method block evaluated immediately [OK]
- Thinking @name is dynamically resolved inside the block
- Expecting 'Hello, Alice!' due to misunderstanding of closure
- Confusing instance and class scope
class Calculator
def initialize(x)
@x = x
self.class.define_method(:square) { @x * @x }
end
end
calc = Calculator.new(4)
puts calc.squareSolution
Step 1: Analyze where define_method is called
define_methodonself.classdefines an instance methodsquare. The block executes in instance context.Step 2: Understand closure and instance variable scope
@xresolved on instance:4 * 4 = 16. No capture issue, no error.Final Answer:
No error, outputs 16 -> Option AQuick Check:
Instance vars work in class-level define_method [OK]
- Thinking method undefined for instances
- Expecting syntax error
- Believing nil * nil error from poor capture
Person has a greet method that correctly uses its own @name?
class Person
def initialize(name)
@name = name
self.class.define_method(:greet) { "Hello, #{@name}!" }
end
end
p1 = Person.new("Bob")
p2 = Person.new("Carol")
puts p1.greet
puts p2.greetSolution
Step 1: Understand the problem with class-level define_method
Class-leveldefine_methodininitializeredefines a shared instance method each time (inefficient, problematic for local var closures). Instance vars work via dynamic lookup.Step 2: Use define_singleton_method to define method per instance
define_singleton_methoddefines on the instance's singleton class, giving each its owngreetaccessing own@name.Final Answer:
Define greet method inside initialize usingdefine_singleton_method-> Option AQuick Check:
Use define_singleton_method for per-instance closures [OK]
- Trying to pass instance vars as parameters to class method
- Using class variables instead of instance variables
- Defining method with def inside initialize incorrectly
Ready to prove it?
Pass the test and this pattern moves unknown
