【发布时间】:2013-07-07 08:04:34
【问题描述】:
我一直在阅读一些关于 Ruby 的 mixin 方法的文章,extend 和 include,但我仍然不太确定这种行为。我知道extend 会将给定模块的实例方法作为单例方法添加到进行扩展的模块中,并且include 本质上会将模块的内容(方法、常量、变量)附加到执行扩展的模块中包括,在接收器中有效地定义它们。
但是,经过一些修改,试图了解行为将如何表现,我有几个问题。这是我的测试设置:
module Baz
def blorg
puts 'blorg'
end
end
module Bar
include Baz
def blah
puts 'blah'
end
end
module Foo
extend Bar
end
class Bacon
extend Bar
end
class Egg
include Bar
end
正如我所料,模块Bar 获得了在Baz (#blorg) 中定义的实例方法,就好像它们是由于包含方法而在其自身中定义的一样,而类Bacon 获得了单例方法 Bacon::blah 和 Bacon::blorg 的扩展。
Bacon.blah # => blah
Bacon.blorg # => blorg
而Egg 类获得Bar(#blah 和现在的#blorg)中定义的方法作为实例方法。
Egg.new.blah # => blah
Egg.new.blorg # => blorg
我明白了,这很好。
但是,我不明白使用 #ancestors 和 #is_a? 方法得到的响应。
Bacon.ancestors # => [Bacon, Object, Kernel, BasicObject]
Bacon.is_a? Bar # => true
Egg.ancestors # => [Egg, Bar, Baz, Object, Kernel, BasicObject]
Egg.is_a? Bar # => false
似乎扩展一个模块会导致#is_a?方法在查询该模块时返回true,但它没有添加到类的祖先中,反之亦然:该类包含被包含的模块,但#is_a? 方法在查询时返回false。为什么会这样?
【问题讨论】:
-
+1 这个问题的格式很好。
标签: ruby inheritance include extend