包括一个模块作为How can I reverse ruby's include function的后续,这是很好的回答,但事实证明我的简化实际问题意味着解决方案不适用。如何“替换”通过红宝石包括功能
现在我碰到这样的(名称变更为保护身份!):
module OldFormHelpers
def foo
puts "foo"
end
def bar
puts "bar"
end
end
module Helpers
include OldFormHelpers
end
这给了我:
Helpers.instance_methods
=> ["bar", "foo"]
Helpers.ancestors
=> [Helpers, OldFormHelpers]
这是代码,我真的没有访问修改,而不分叉。
我想要做的是创建一个新模块;
module BetterFormHelpers
def foo
puts "better foo"
end
end
这需要从OldFormHelpers
删除的行为,然后在新的东西从BetterFormHelpers
以前的解决方案增加了使用undef_method
像这样:
Helpers.module_eval do
OldFormHelpers.instance_methods do |m|
undef_method(m)
end
end
然而,包括后BetterFormHelpers
,Helpers.instance_methods不包含“foo”。这样做的原因在http://ruby-doc.org/core/classes/Module.src/M001652.html
使用remove_method
告诉我,Helpers
不具有“foo”的方法进行说明,所以我想我需要去除的祖先链第一包含的一些方法...
这会变得有点长,所以我停止了将这么多片段放到最后,但是我添加了一个irb会话来显示undef/remove的行为,然后添加一个include。
“这是我没有真正有权修改的代码”:猴子补丁不是一个选项吗? – 2010-03-09 16:13:01
猴子补丁是一个选项,有点 - 但是我们要替换的模块的工作方式,它定义了模块,然后包含它们 - 将代码注入到链中以阻止包含发生是非常棘手的。尽管在追求这条路线一段时间之后,我开始更多地朝这个方向倾斜。 – Glenjamin 2010-03-09 16:42:49