2014-10-04 54 views
2

method_missing被調用時,爲什麼我不能在Object中看到@obj.instance_variablesObject中的實例變量在哪裏?

module Arena 
    class Place 
    def initialize obj 
     @obj = obj 
     method_missing_in_obj 
     @obj.instance_variable_set(:@unit, '10') 
     puts @obj.instance_variables 
     yield @obj 
    end 
    def method_missing_in_obj 
     def @obj.method_missing method, *args, &blk 
     puts @obj.instance_variables 
     super 
     end 
     self 
    end 
    end 
end 

Arena::Place.new(Object.new) do |obj| 
    puts obj.instance_variable_get(:@unit) 
    puts obj.foo 
end 

$> ruby test_me.rb

=> @unit 
=> 10 
=> in `method_missing': undefined method `foo' for #<Object:0x007fd89b1c96e0 @unit="10"> (NoMethodError) 

回答

2

這是個微妙的問題!問題是當你定義@obj.method_missing時你打電話給@obj.instance_variables。請記住,它定義了一個在@obj的單例類中的方法,所以當你在方法定義中使用@obj時,請求@obj的實例變量@objnil(並且nil沒有實例變量)。

您只需刪除顯式接收器,因爲@obj隱式地是其單例類中定義的方法的接收器。

def method_missing_in_obj 
    def @obj.method_missing method, *args, &blk 
    puts instance_variables 
    super 
    end 
    self 
end