📖 Scenario: Imagine you are creating a simple program to manage a list of pets. Each pet has a name and a type (like dog, cat, or bird). You want to add special methods dynamically to greet each pet by its type.
🎯 Goal: You will build a Ruby class called Pet that uses define_method to create dynamic greeting methods for each pet type. This way, you can call a method like greet_dog or greet_cat to get a custom greeting.
📋 What You'll Learn
Create a class called Pet with an initializer that takes name and type.
Create a list of pet types: ["dog", "cat", "bird"].
Use define_method inside the Pet class to add greeting methods dynamically for each pet type.
Print the greeting message by calling the dynamic method for a pet instance.
💡 Why This Matters
🌍 Real World
Dynamic method creation helps when you want to add many similar methods without writing each one by hand, saving time and reducing errors.
💼 Career
Understanding <code>define_method</code> is useful for Ruby developers working on flexible libraries, DSLs, or metaprogramming tasks.
Progress0 / 4 steps
1
Create the Pet class with initializer
Create a class called Pet with an initialize method that takes name and type as parameters and saves them as instance variables.
Ruby
Hint
Use def initialize(name, type) and set @name = name and @type = type.
2
Create a list of pet types
Create an array called pet_types with the exact values ["dog", "cat", "bird"].
Ruby
Hint
Use square brackets [] to create the array with the three pet types as strings.
3
Use define_method to add dynamic greeting methods
Inside the Pet class, use pet_types.each do |type| ... end and inside the block use define_method to create a method named greet_#{type} that returns the string "Hello, I am a #{type} named #{@name}!".
Ruby
Hint
Use define_method("greet_#{type}") do ... end inside the loop to create methods dynamically.
4
Create a pet and call the dynamic greeting method
Create a Pet instance called my_pet with name "Buddy" and type "dog". Then print the result of calling my_pet.greet_dog.
Ruby
Hint
Create the pet with Pet.new("Buddy", "dog") and call greet_dog on it.
Practice
(1/5)
1. What does define_method do in Ruby?
easy
A. Creates a method dynamically during program execution
B. Deletes an existing method from a class
C. Calls a method with given arguments
D. Defines a constant value in a class
Solution
Step 1: Understand the purpose of define_method
define_method allows creating methods while the program runs, not just when writing code.
Step 2: Compare options with define_method behavior
Only Creates a method dynamically during program execution correctly describes dynamic method creation. Other options describe unrelated actions.
Final Answer:
Creates a method dynamically during program execution -> Option A
Quick Check:
define_method = dynamic method creation [OK]
Hint: define_method creates methods while program runs [OK]
Common Mistakes:
Thinking define_method deletes methods
Confusing define_method with method calls
Assuming define_method defines constants
2. Which of the following is the correct syntax to define a method named greet dynamically inside a class using define_method?
easy
A. define_method('greet') { puts 'Hello' }
B. define_method :greet puts 'Hello' end
C. def define_method :greet puts 'Hello' end
D. define_method greet puts 'Hello'
Solution
Step 1: Recall correct define_method syntax
The method name can be a symbol or string, and the method body is given as a block.
Step 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 A
Quick Check:
define_method syntax = method name + block [OK]
Hint: Use parentheses and block for define_method syntax [OK]
Common Mistakes:
Omitting parentheses around method name
Not using a block for method body
Writing def inside define_method incorrectly
3. What will be the output of this Ruby code?
class Person
[:walk, :run].each do |action|
define_method(action) { puts "I can #{action}" }
end
end
p = Person.new
p.walk
p.run
medium
A. I can run
I can run
B. I can walk
I can run
C. NoMethodError for walk
D. SyntaxError
Solution
Step 1: Understand the loop and define_method usage
The code loops over [:walk, :run] using each do |action| and defines two methods dynamically. Ruby blocks capture the loop variable action by value for each iteration, so each method captures its own action value.
Step 2: Trace method calls on instance
p.walk prints "I can walk" and p.run prints "I can run" as expected.
Final Answer:
I can walk
I can run -> Option B
Quick Check:
Blocks capture loop variable per iteration [OK]
Hint: Blocks in Ruby loops capture loop variable per iteration [OK]
Common Mistakes:
Expecting same output for both methods (confuses closure capture)
Thinking methods are not defined
Confusing syntax with errors
4. Identify the error in this code snippet:
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)
medium
A. Wrong number of arguments passed to methods
B. Missing parentheses in method calls
C. The variable op inside the block always refers to the last symbol
D. Syntax error in define_method block
Solution
Step 1: Understand variable capture in blocks
The block uses op inside the method body, but op is 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 if op == :subtract, so add will subtract incorrectly.
Final Answer:
The variable op inside the block always refers to the last symbol -> Option C