我一直在阅读一些关于 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
并且类将(和 now ) 中Egg
定义的方法作为实例方法获得。Bar
#blah
#blorg
Egg.new.blah # => blah
Egg.new.blorg # => blorg
我明白了,所以这很好。
但是,我不明白使用#ancestors
and#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
在查询时返回。为什么会这样?