查看此instance_eval示例:
class KlassWithSecret
def initialize
@secret = 99
end
def get
@secret
end
end
k = KlassWithSecret.new
k.instance_eval { @secret }
print k.get
我向get
添加了KlassWithSecret
方法。
这是运行程序的结果:
>ruby InstanceEvalTest.rb
99
那么,instance_eval
这里是否以某种方式调用initialize
方法?
我认为通过阅读这篇有用的post,我对此方法有所了解。但我还在黑暗中。
答案 0 :(得分:2)
调用initialize
方法后,Ruby会自动调用new
方法。 instance_eval
运行您在对象的上下文中提供的块。这意味着它可以访问KlassWithSecret
类中的正常代码行。
@secret
是实例变量,这意味着它属于KlassWithSecret
的实例。由于我们正在{ @secret }
个实例的上下文中评估KlassWithSecret
,因此我们可以访问@secret
。
答案 1 :(得分:2)
k.instance_eval
使您可以访问所有实例变量(此处只是@secret
)和所有私有方法(如果有的话)。它执行块中的代码,在这种情况下返回99
的值@secret
。然后print k.get
打印该值并返回nil
。
如果该块已{ @secret = 'cat' }
,则k.instance_val
会更改@secret
的值(并返回新值)。
使用instance_eval
,class_eval
,class < self
和其他元编程构造时,您会发现使用self
语句跟踪puts
的值很有帮助。例如:
k = KlassWithSecret.new #=> #<KlassWithSecret:0x00000101897810 @secret=99>
self #=> main
k.instance_eval { puts "self=#{self}"; @secret }
"self=#<KlassWithSecret:0x00000101897810>"
#=> 99