【发布时间】:2012-07-29 09:12:27
【问题描述】:
我想在不破坏查找链的情况下合并两个 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 的反馈得到两个答案后,我完全改变了问题,所以如果它们看起来无关紧要]
【问题讨论】:
-
为什么要这样做?这闻起来像XY problem。正如所写,你想做的事情听起来是个坏主意。
-
我正在构建一个元编程框架,这样逻辑就消失了。 :( 实际代码看起来(或工作)不像这样
标签: ruby module mixins method-resolution-order