为什么 Ruby 的前缀在与模块一起使用时与 类 的行为不同?
Is there a reason why Ruby's prepend behaves differently when used with modules versus classes?
在从 Rails 引擎对模块进行猴子修补时,我们发现如果将模块 B 添加到另一个模块 A,则添加的模块 B 不会添加到 [=36] 的祖先=]es 在 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]
classes B
和 D
都包含 A
,但只有 D
采用新行为,因为它是在我们调用 prepend
.
相比之下,我们了解到 class 继承不会表现出这种行为:
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]
这一次,class和 B
和 D
都采用了新的行为,即使 B
是在我们调用 prepend
之前定义的。
prepend
与模块一起使用时与 classes 一起使用时的行为不同是否有原因?我假设这是设计使然,但在将 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]
在从 Rails 引擎对模块进行猴子修补时,我们发现如果将模块 B 添加到另一个模块 A,则添加的模块 B 不会添加到 [=36] 的祖先=]es 在 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]
classes B
和 D
都包含 A
,但只有 D
采用新行为,因为它是在我们调用 prepend
.
相比之下,我们了解到 class 继承不会表现出这种行为:
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]
这一次,class和 B
和 D
都采用了新的行为,即使 B
是在我们调用 prepend
之前定义的。
prepend
与模块一起使用时与 classes 一起使用时的行为不同是否有原因?我假设这是设计使然,但在将 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]