class MyFooClass
attr_reader :value
def initialize(value)
@value = value
end
# In order to say foo.bar, the class of foo must define bar.
def bar
puts "bar sent to #{self}"
# return a class where method_missing is defined,
# and pass it a reference to foo
MyBarClass.new(self)
end
end # MyFooClass
class MyBarClass
def initialize(foo)
@foo = foo
end
def method_missing(name, *args, &block)
puts "missing #{name} in #{self.class}"
self.class.class_eval %Q{
puts "about to define #{name}"
def #{name}(*args)
puts "in #{name} on self=#{self} with args=#{args}"
puts "foo is #{@foo} and it's value is <#{@foo.value}>"
end
}
puts "after define, execute #{name}"
self.send(name, *args)
end
end # MyBarClass
foo = MyFooClass.new('value of foo') # result of an expression
foo.bar.baz 'arg1' # define baz for future reference and execute it
print 'MyBarClass.instance_methods : '; p MyBarClass.instance_methods(false)
実行:
$ ruby -w t.rb
bar sent to #<MyFooClass:0x10195c750>
missing baz in MyBarClass
about to define baz
after define, execute baz
in baz on self=#<MyBarClass:0x10195c6b0> with args=arg1
foo is #<MyFooClass:0x10195c750> and it's value is <value of foo>
MyBarClass.instance_methods : ["baz", "method_missing"]