一般来说,模块永远不能覆盖类中的方法
它包含在其中。这是因为模块包含仅适用于
像子类化。超类不能覆盖其子类'
方法,你也不希望它。
当一个模块被包含在一个类中时,该模块被插入
就在类的祖先链中的类之后。打电话
class 中的super 将调用 module 的实现。
class Something
module PreExtension; end
module PostExtension; end
include PreExtension
include PostExtension
end
Something.ancestors # => [Something, Something::PostExtension, Something::PreExtension, Object, Kernel]
每当在 Something 上调用方法时,Ruby 都会查看
这个列表按顺序调用它找到的第一个实现。
如果实现调用super,它会继续查找并找到
下一个。
这意味着后面包含的模块优先于
较早包含的模块,并且可以调用super 获取较早的
模块的实现。这是因为包含的模块是
插入到祖先链中直接在类之后。这
是提到的路由代码 edgerunner 是如何工作的。那个代码
将所有内容放在模块中,如下所示:
class SomethingNew
module Base
def my_method
puts "(A)"
end
end
module Extension
def my_method
puts "(B)"
super
end
end
include Base
include Extension
end
SomethingNew.new.my_method
# Output:
# >> (B)
# >> (A)
SomethingNew.ancestors # => [SomethingNew, SomethingNew::Extension, SomethingNew::Base, Object, Kernel]
这就是为什么 alias_method_chain 首先存在的原因。如果不能将基本代码放入模块中,我不确定如何完成 alias_method_chain 的等效操作。