now - 5}.merge(options))
end
Metaprogramming Techniques | 31
def age
Time.now - self[:initialized_at]
end
end
settings = Settings.new :use_foo_bar => true
# Method calls are delegated to the object
settings[:use_foo_bar] # => true
settings.age # => 5.000301
The Settings constructor calls super to set the delegated object to a new hash. Note
the difference between composition and inheritance: if we had inherited from Hash,
then Settings would be a hash; in this case, Settings has a hash and delegates to it.
This composition relationship offers increased flexibility, especially when the object
to be delegated to may change (a function provided by SimpleDelegator).
The Ruby standard library also includes Forwardable, which provides a simple interface
by which individual methods, rather than all undefined methods, can be delegated
to another object. ActiveSupport in Rails provides similar functionality with a
cleaner API through Module#delegate:
class User < ActiveRecord::Base
belongs_to :person
delegate :first_name, :last_name, :phone, :to => :person
end
Monkeypatching
In Ruby, all classes are open. Any object or class is fair game to be modified at any
time. This gives many opportunities for extending or overriding existing functionality.
This extension can be done very cleanly, without modifying the original definitions.
Rails takes advantage of Ruby??™s open class system extensively.
Pages:
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62