Ruby 为什么instance_exec和class_exec有这种不同的行为?
我从Ruby 为什么instance_exec和class_exec有这种不同的行为?,ruby,metaprogramming,Ruby,Metaprogramming,我从instance\u exec class KlassWithSecret def initialize @secret = 99 end end k = KlassWithSecret.new k.instance_exec(5) {|x| @secret+x } #=> 104 我对instance_exec为什么这样做的理解是在下图中,它在其singleton类中添加了@secret+5 +------------------
instance\u exec
class KlassWithSecret
def initialize
@secret = 99
end
end
k = KlassWithSecret.new
k.instance_exec(5) {|x| @secret+x } #=> 104
我对instance_exec为什么这样做的理解是在下图中,它在其singleton类中添加了@secret+5
+-----------------------+
| singleton class do |
| def method1 |
| ... |
| end |
| ... |
| @secret + 5 |
| end |
| |
| |
+-----------+-----------+
|
+---------+-------+
| instance k |
| @secret |
| |
+-----------------+
因此,我提出了使用类_exec获得相同结果的代码
k.singleton_class.class_exec(5) {|x| @secret + x}
它给了我一个@secret is nil error,我想知道为什么会这样,以及我的理解有什么问题
更新:
我注意到k.instance_exec{binding}和k.singleton_class.class_exec{binding}具有不同的绑定对象,因此它们必须是不同的。我仍然想知道它们在幕后是如何工作的
实例_exec
是用C编写的,C-api允许您指定在执行方法时self的值
在它成为ruby之前,人们通过在singleton类上定义一个方法并调用该方法来实现它,而不仅仅是在singleton类的上下文中执行东西(您可以在activesupport 2.x或rspec_core的instance_eval_with_args
中看到这一点)
对象的singleton类本身就是一个对象,因此它有自己的一组实例变量,这些变量不与相应的对象共享,而instance_exec是用C编写的,C-api允许您在执行方法时指定self的值 在它成为ruby之前,人们通过在singleton类上定义一个方法并调用该方法来实现它,而不仅仅是在singleton类的上下文中执行东西(您可以在activesupport 2.x或rspec_core的
instance_eval_with_args
中看到这一点)
对象的singleton类本身就是一个对象,因此它有自己的一组实例变量,这些变量不与相应的对象共享