爲什麼在class_eval
之前創建的a
在代碼中有權訪問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
如何在幕後工作?
爲什麼在class_eval
之前創建的a
在代碼中有權訪問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
如何在幕後工作?
ruby中的類已打開。由於Hello
是用一個新的方法給出的,因此在所有實例上的方法調度都被這個更新了。如果你想擴展a
只,呼籲class_eval
上a
的eigenclass:
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>
爲什麼
a
創建之前class_eval
代碼訪問world
?
它沒有。方法存儲在模塊中,而不是實例。 (好吧,模塊是Module
實例,但是這無關緊要這裏)。所有a
知道的是,它的Hello
的實例,即其class
指針指向Hello
(再次,從技術上講,這不是事實,其class
指針指向它的單例類和它的單例類的superclass
指針指向Hello
,但在這裏也是不相關的)。當a
獲得world
消息發送world
消息它檢查它的類,Hello
,爲一個world
方法,並且確實有一個,因爲它是在消息發送之前添加的,因此它執行它。
class_eval
如何在幕後工作?
這與class_eval
沒有任何關係,它可以在沒有元編程的情況下以完全相同的方式工作。 class_eval
這裏是一條紅鯡魚:
class Hello; end
a = Hello.new
class Hello; def world; puts "Hi" end end
b = Hello.new
a.world # "Hi"
b.world # "Hi"
你不需要'class_eval {'...'}'。 – sawa
@sawa我是複製粘貼的奴隸。 Thx,已更新。 – mudasobwa