理解简单的`instance_eval`示例

时间:2014-11-30 03:08:55

标签: ruby

查看此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,我对此方法有所了解。但我还在黑暗中。

2 个答案:

答案 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_evalclass_evalclass < self和其他元编程构造时,您会发现使用self语句跟踪puts的值很有帮助。例如:

k = KlassWithSecret.new #=> #<KlassWithSecret:0x00000101897810 @secret=99>
self #=> main
k.instance_eval { puts "self=#{self}"; @secret }
"self=#<KlassWithSecret:0x00000101897810>"
  #=> 99