当monkey从Rails引擎中修补模块时,我们发现如果将模块B预附加到另一个模块a,则预附加的模块B将不会添加到prepend
之前已经包含模块a的类的祖先中。举例说明:
module A
def a
puts 'a'
end
end
class B
include A
end
module C
def a
puts 'c'
end
A.prepend self
end
class D
include A
end
B.new.a # prints: a
D.new.a # prints: c
B.ancestors #=> [B, A, Object, Kernel, BasicObject]
D.ancestors #=> [D, C, A, Object, Kernel, BasicObject]
两个类CCD_ 2&D
包括A
,但只有D
采用新的行为,因为它是在我们调用prepend
之后定义的行为。
相比之下,我们了解到类继承并没有表现出这种行为:
class A
def a
puts 'a'
end
end
class B < A
end
module C
def a
puts 'c'
end
A.prepend self
end
class D < A
end
B.new.a # prints: c
D.new.a # prints: c
B.ancestors #=> [B, C, A, Object, Kernel, BasicObject]
D.ancestors #=> [D, C, A, Object, Kernel, BasicObject]
这一次,两个类B
&D
采取了新的行为,即使B
是在我们调用prepend
之前定义的。
prepend
在与模块和类一起使用时表现不同,这是有原因的吗?我假设这是设计的,但在使用带有模块的prepend
时,它确实会出现问题。
https://bugs.ruby-lang.org/issues/9573显示了关于类和模块的类似行为。错误报告发布于2014年,直到2020年才关闭。根据这份报告,我已经手动确认
- 此行为仍然出现在ruby 2.7.2p137(2020-10-01修订版5445e04352([x86_64-linux]中,但是
- 此行为不再出现在ruby 3.0.0p0(2020-12-25修订版95aff21468([x86_64-linux]中