我想在不破坏查找链的情况下合并两个 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
来反映这种行为
还有比这更好的解决方案吗?理想情况下,我希望在调用BothAnB.ancestors
.
[注意:在根据 Phrogz 的反馈得到两个答案后,我完全改变了问题,所以如果它们看起来无关紧要,那就是]