A lot of the magic you see in Rubyland has to do with metaprogramming, which is simply writing code that writes code for you. Ruby's `attr_accessor`, `attr_reader`, and `attr_writer` are all simple metaprogramming, in that they create two methods in one line, following a standard pattern. Rails does a whole lot of metaprogramming with their relationship-management methods like `has_one` and `belongs_to`.
But it's pretty simple to create your own metaprogramming tricks using `class_eval` to execute dynamically-written code.
The following example allows a wrapper object to forwards certain methods along to an internal object:
class Wrapper
attr_accessor :internal
def self.forwards(*methods)
methods.each do |method|
define_method method do |*arguments, &block|
internal.send method, *arguments, &block
end
end
end
forwards :to_i, :length, :split
end
w = Wrapper.new
w.internal = "12 13 14"
w.to_i # => 12
w.length # => 8
w.split('1') # => ["", "2 ", "3 ", "4"]
The method `Wrapper.forwards` takes symbols for the names of methods and stores them in the `methods` array. Then, for each of those given, we use `define_method` to create a new method whose job it is to send the message along, including all arguments and blocks.
A great resource for metaprogramming issues is [Why the Lucky Stiff's "Seeing Metaprogramming Clearly"][1].
[1]:
[To see links please register here]