gpt4 book ai didi

ruby - Ruby如何解决 'diamond' mixin中的方法查找?

转载 作者:太空宇宙 更新时间:2023-11-03 17:20:17 24 4
gpt4 key购买 nike

Ruby 的版本是这样的:

% ruby -v
ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-darwin17]

我想到了如果我们在 Ruby 中以“菱形”形式混合会怎样。

这是一个例子:

module M3; end
module M1
prepend M3
end

module M2
prepend M3
end

class Base
include M1
include M2
end

p Base.ancestors # [Base, M3, M2, M1, Object, Kernel, BasicObject]

结果是[Base, M3, M2, M1, Object, Kernel, BasicObject]

即使您在 Base 类中将模块 M2 的混合类型从 include 更改为 prepend,结果是一样的:

module M3; end
module M1
prepend M3
end

module M2
prepend M3
end

class Base
include M1
prepend M2 # <= change mixin type
end

p Base.ancestors # [Base, M3, M2, M1, Object, Kernel, BasicObject]

结果也是 [Base, M3, M2, M1, Object, Kernel, BasicObject]。我觉得很奇怪。

Ruby如何解决'diamond'mixin中的方法查找?

注意)我已经了解了Ruby 中方法查找的基础知识,https://docs.ruby-lang.org/en/trunk/syntax/refinements_rdoc.html#label-Method+Lookup .

最佳答案

我的理解是:

  • includeprepend在每个步骤中在相关模块/类之间建立部分关系(祖先关系),并且
  • 在后面的步骤中不能反驳祖先关系。

让我们开始:

module M1; end
module M2; end
module M3; end
class Base; end

并按照每个步骤进行操作。前三个步骤应该很简单:

Base.ancestors
#=> [Base, Object, Kernel, BasicObject]

M1.prepend M3
M1.ancestors
# => [M3, M1]

M2.prepend M3
M2.ancestors
#=> [M3, M2]

现在,您关键的第一步是 Base.include M1 .这将插入 M1 的祖先(整个 [M3, M1] block )就在 Base 的右边之前Object :

Base.include M1
Base.ancestors
#=> [Base, M3, M1, Object, Kernel, BasicObject]

下一步是Base.prepend M2 .这会尝试插入 M2 的祖先(整个 [M3, M2] block )就在 Base 的左边.但请注意,这会导致 Base 之间的矛盾关系。和 M3 .

Base.prepend M2
Base.ancestors
#=> Cannot be [M3, M2, Base, M3, M1, Object, Kernel, BasicObject]

因为已经确定M3出现在 Base 的右侧,它能做的最好的地方[M3, M2]就是放在Base的右边:

Base.prepend M2
Base.ancestors
#=> [Base, M3, M2, M1, Object, Kernel, BasicObject]

似乎放置 M2Base 的右侧与 Base.prepend M2 的意图相矛盾.但这可以取消/修改以适应现场,而 Base 之间已经建立的关系和 M3以后不能取消。

事实上,当没有办法满足已经建立的关系时,就会报错:

module M4; end
module M5; end
M4.include M5
M5.include M4 #>> ArgumentError: cyclic include detected

关于ruby - Ruby如何解决 'diamond' mixin中的方法查找?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50102032/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com