*_missing、*method_added 方法


如果傳遞訊息給物件,而物件最終沒有合適的方法可以回應訊息,則會呼叫method_missing方法,傳入代表方法的Symbol實例、呼叫方法時的引數與程式區塊。例如:
>> class Some
>>     def method_missing(mth, *args, &block)
>>         puts "No such method #{mth} with #{args} and #{block}"
>>     end
>> end
=> nil
>> Some.new.a {}
No such method a with [] and #<Proc:0x2643de0@(irb):7>
=> nil
>>


BasicObject 中看過實際method_missing的應用。另一個常數應用,就是不以is a方式增加類別功能(也就是不使用繼承),而以has a方式動態為類別實例增加功能時,為了不逐一定義同名方法時,會使用如下方式:
>> class Some
>>     def action1
>>         puts "action1"
>>     end
>>     def action2
>>         puts "action2"
>>     end
>> end
=> nil
>> class Other
>>     def initialize(s)
>>         @s = s
>>     end
>>     def action3
>>         puts "action3"
>>     end
>>     def method_missing(mth, *args, &block)
>>         @s.send(mth, *args, &block)
>>     end
>> end
=> nil
>> other = Other.new(Some.new)
=> #<Other:0x275a318 @s=#<Some:0x275a330>>
>> other.action1
action1
=> nil
>> other.action2
action2
=> nil
>> other.action3
action3
=> nil
>>


如果類別定義有const_missing方法,在指定的常數不在類別中定義時就會呼叫。例如:
>> class Some
>>     def self.const_missing(const)
>>         puts "No such constant #{const}"
>>     end
>> end
=> nil
>> Some::X
No such constant X
=> nil
>>


如果類別定義有method_added方法,之後若類別中定義了實例方法,就會呼叫該方法:
>> class Some
>>     def self.method_added(mth)
>>         puts "Some just defined method - #{mth}"
>>     end
>> end
=> nil
>> class Some
>>     def some; end
>> end
Some just defined method - some
=> nil
>>


如果實例上定義有singleton_method_added方法,之後若該實例定義了單例方法,就會呼叫該方法:
>> o = Object.new
=> #<Object:0x27705f0>
>> def o.singleton_method_added(mth)
>>     puts "#{self} just defined singleton method - #{mth}"
>> end
#<Object:0x27705f0> just defined singleton method - singleton_method_added
=> nil
>> def o.some; end
#<Object:0x27705f0> just defined singleton method - some
=> nil
>>


從上例中可以看到,由於singleton_method_added本身也是單例方法,因而在實例上定義singleton_method_added後,馬上就會觸發。