While monkey-patching a module from a Rails engine, we found that if you prepend a module B to another module A, the prepended module B won't be added to the ancestors of classes that have already included module A prior to the prepend. To illustrate:
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]
Run Code Online (Sandbox Code Playgroud)
Both classes B & D include A, but only D takes the new behavior as it's the one defined after we call prepend.
In contrast, we learned that class inheritance does not exhibit this behavior:
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]
Run Code Online (Sandbox Code Playgroud)
This time, both classes B & D have taken the new behavior, even if B was defined before we called prepend.
prepend与模块和类一起使用时,是否有不同的行为?我假设这是设计使然,但在与模块一起使用时确实存在问题prepend。
https://bugs.ruby-lang.org/issues/9573显示了有关类和模块的类似行为。该错误报告于 2014 年发布,直到 2020 年才关闭。根据该报告,我手动确认了
| 归档时间: |
|
| 查看次数: |
443 次 |
| 最近记录: |