Metaprogramming means writing code that writes or modifies code at runtime. Ruby makes this remarkably easy — and Rails relies on it heavily.
method_missing
Intercept calls to methods that don't exist:
Ruby
class DynamicGreeter
def method_missing(method_name, *args)
if method_name.to_s.start_with?("greet_in_")
language = method_name.to_s.sub("greet_in_", "")
greet(language, *args)
else
super
end
end
def respond_to_missing?(method_name, include_private = false)
method_name.to_s.start_with?("greet_in_") || super
end
private
def greet(language, name)
case language
when "english" then "Hello, #{name}!"
when "nepali" then "Namaste, #{name}!"
when "hindi" then "Namaskar, #{name}!"
else "Hi, #{name}!"
end
end
end
greeter = DynamicGreeter.new
puts greeter.greet_in_english("Ram") # "Hello, Ram!"
puts greeter.greet_in_nepali("Sita") # "Namaste, Sita!"define_method
Create methods dynamically:
Ruby
class Person
%w[name age city].each do |field|
define_method(field) do
instance_variable_get("@#{field}")
end
define_method("#{field}=") do |value|
instance_variable_set("@#{field}", value)
end
end
end
p = Person.new
p.name = "Sita"
p.age = 21
puts p.name # "Sita"send
Call methods by name:
Ruby
class Greeter
def hello(name) "Hello, #{name}!" end
def goodbye(name) "Goodbye, #{name}!" end
end
g = Greeter.new
method_name = :hello
puts g.send(method_name, "Ram") # "Hello, Ram!"Tips
- Metaprogramming is powerful but can make code harder to debug.
- Use it when it simplifies (DRY principle), avoid when it obscures.
- Prefer
define_methodovereval— it's safer and faster.
🎉 You have completed the Ruby course!