为什么代码a
之前创建的class_eval
可以访问world
?
class Hello; end
a = Hello.new
Hello.class_eval {def world; puts "Hi" end}
b = Hello.new
a.world #=> "Hi"
b.world #=> "Hi"
class_eval
如何在幕后工作?
答案 0 :(得分:6)
ruby中的类是开放的。当使用新方法给出Hello
时,所有实例上的方法调度都已更新。如果您只想展开a
,请在class_eval
的本征类上致电a
:
class Hello; end
a = Hello.new
class << a; def world; puts "Hi" end end
# or, the equivalent:
# a.singleton_class.class_eval { def world; puts "Hi" end }
b = Hello.new
a.world #⇒ "Hi"
b.world #⇒ NoMethodError: undefined method `world' for #<Hello>
答案 1 :(得分:0)
为什么代码
a
之前创建的class_eval
可以访问world
?
它没有。方法存储在模块中,而不是实例中。 (好吧,模块是Module
的实例,但这里不相关。)所有a
都知道它是Hello
的一个实例,即它的{{} 1}}指针指向class
(再次,从技术上讲,它不是真的,它的Hello
指针指向它的单例类及其单例类的class
指针点到superclass
,但这也与此无关)。当Hello
发送a
消息时,它会检查其类world
,以查找Hello
方法,果然,有一个因为它是在消息之前添加的发送,所以它执行它。
world
如何在幕后工作?
这与class_eval
无关,如果没有元编程,它的工作方式完全相同。 class_eval
在这里是一个红鲱鱼:
class_eval