2014-10-04 50 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