我一直在阅读关于Ruby混入方法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
。为什么会这样呢?