gpt4 book ai didi

ruby - 合并两个 Ruby 模块但不包含

转载 作者:数据小太阳 更新时间:2023-10-29 07:29:06 25 4
gpt4 key购买 nike

我想在不破坏查找链的情况下合并两个 Ruby 模块。基本上,我希望 BothAnB 的行为就像我将 A 和 B 中的文本源代码连接在一起,并用新的 foo 替换旧的一样。当 MRO 线性化继承菱形时会出现问题。

module O
def foo; puts "O" end
end

module A
include O
def foo; puts "A"; super end
def aaa; puts "aaa" end
end

module B
include O
def foo; puts "B"; super end
def bbb; puts "bbb" end
end

module BothAnB
#insert magic here such that a class C that includes BothAnB:
# C.new.foo => B O
# C.new.aaa => aaa
# C.new.bbb => bbb
end

module JustA
#insert magic here such that a class C that includes JustA:
# C.new.foo => A O
# C.new.aaa => aaa
# C.new.bbb => FAIL
end
#and similarly JustB

A 和 B 是相当复杂的模块,可以有很深的继承链(这是一个允许程序员这样做的元编程框架)。

Include B, A 不起作用,因为不是查找 BothAnB->B->A->O,我需要它是 BothAnB->B->O(并且可选 ->A)。我已经接近了:

  • 深度克隆A的整个继承树(去除菱形)
  • undef_method 在 A 的克隆上删除在 B 中找到的方法
  • Module 创建一个新方法来反射(reflect)这种行为

还有比这更好的解决方案吗?理想情况下,我希望在调用 BothAnB.ancestors 时至少保留一些可识别的模块。

[注意:在根据 Phrogz 的反馈得到两个答案后,我完全改变了问题,所以如果它们看起来不相关,那么它们就是]

最佳答案

这是另一个可能的技巧:

module BothAnB
include A
include O.clone
include B
end

class C
include BothAnB
end

C.new.foo
C.new.aaa
C.new.bbb

# output:
B
O
aaa
bbb

这里我们让 B#foo 中的 super 指向 O#foo 而不是 A#foo .

如果 O 很复杂并且包含其他东西,它可能需要更多这样的魔法:

module O
# don't do this:
# include Whatever

# do this instead:
def self.included(base)
base.send(:include, Whatever.clone)
end
end

关于ruby - 合并两个 Ruby 模块但不包含,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11742890/

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