我有这个模块:
module MyMod
def +(other)
puts "hello"
end
end
这将成功覆盖
+
的Fixnum
:Fixnum.prepend(MyMod)
123 + :test # outputs "hello"
假设我需要对
+
和其他对象重写Fixnum
运算符。这将成功覆盖+
和其他对象的Fixnum
:Fixnum.prepend(MyMod)
Object.include(MyMod)
123 + :test # outputs "hello"
但如果我更改
prepend
和include
的顺序,则覆盖无效:Object.include(MyMod)
Fixnum.prepend(MyMod)
123 + :test # error: -:10:in `+': :test can't be coerced into Fixnum (TypeError)
为什么
include
和prepend
的顺序在这里有这种效果? 最佳答案
参见Module#prepend_features的文档:
当这个模块在另一个模块中前置时,ruby调用这个模块中的prepend_特性,将接收模块传入mod。ruby的默认实现是将这个模块的常量、方法和模块变量覆盖到mod,如果这个模块还没有被添加到mod或它的祖先中。另请参见“准备”模块。
因此,prepend
只在其参数尚未添加到接收器或其祖先之一时才执行任何操作。因为Object
是Fixnum
的祖先,所以当在Fixnum.prepend(MyMod)
之后调用时,Object.include(MyMod)
不会执行任何操作。