Ruby [新手提问] 关于 include 和 prepend 的问题

2604249649 · 2022年12月01日 · 最后由 2604249649 回复于 2022年12月01日 · 206 次阅读

我看到《Ruby 元编程(第二版)》中关于多重包含有如下介绍:

每次 include 或 prepend 一个模块的时候,如果该模块已经存在于祖先链中,那么 Ruby 会悄悄地忽略这个包含(include 或 prepend)指令。因此一个模块只会在一条祖先链中出现一次。这种处理方式也许会在未来的 Ruby 版本中改变,但你暂时不用为它担心。

但是我自己试了一下发现貌似不太一样,我的 ruby 环境是 ruby3.1.2,书好像用的是 Ruby2.x

下面是书上举的示例

module M1; end

module M2
  include M1
end

module M3
  prepend M1
  include M2
end

p M3.ancestors #=> [M1, M3, M2]

我对照的书上的示例改了一下代码,交换了 include 和 prepend 的顺序


module M1; end

module M2
  include M1
end

module M3
  include M2 # 交换了 include 和 prepend 的顺序
  prepend M1
end

p M3.ancestors #=> [M1, M3, M2, M1]

输出结果中 M1 在祖先链中出现了两次,这和书上说的不一致,没明白这是为啥?有 Ruby 高手或者大佬能给萌新解释一下么?

这是 ruby 3.1 的一个改动

Module#prepend behavior change
Now, when module is prepended to the class, it always becomes first in the ancestor chain; even if it was already included.

huanghuang 回复

好的明白了,谢谢大佬的解答

2604249649 关闭了讨论。 12月25日 14:27
需要 登录 后方可回复, 如果你还没有账号请 注册新账号