我在instance_exec
class KlassWithSecret
def initialize
@secret = 99
end
end
k = KlassWithSecret.new
k.instance_exec(5) {|x| @secret+x } #=> 104
我对instance_exec的作用的理解如下图所示,它在其单例类中添加@secret + 5
+-----------------------+
| singleton class do |
| def method1 |
| ... |
| end |
| ... |
| @secret + 5 |
| end |
| |
| |
+-----------+-----------+
|
+---------+-------+
| instance k |
| @secret |
| |
+-----------------+
所以我想出了使用class_exec得到相同结果的代码
k.singleton_class.class_exec(5) {|x| @secret + x}
它给我一个@secret是零错误,我想知道为什么它和我的理解有什么不对
更新
我注意到k.instance_exec {binding}和k.singleton_class.class_exec {binding}具有不同的绑定对象,因此它们必须是不同的。我仍然想知道它们是如何在引擎盖下工作的
答案 0 :(得分:1)
instance_exec
是用C语言编写的,c-api允许你指定执行方法时self的值。
在它变成ruby之前,人们通过在单例类上定义一个方法并调用它来实现它,而不仅仅是在singleton类的上下文中执行东西(你可以在activesupport 2.x或rspec_core中看到它) instance_eval_with_args
)
对象的单例类本身就是一个对象,因此有自己的一组实例变量,它们不与相应的对象共享