我将在代码中解释我正在寻找的内容,因为这可能是最简洁的:
module Mixin
def method
puts "Foo"
end
end
class Whatever
include Mixin
end
w = Whatever.new
w.method
=> "Foo"
# some magic here
w2 = Whatever.new
w.method
=> NoMethodError
我曾尝试使用remove_const取消定义Mixin模块,但这似乎对Whatever没有任何影响。我假设#include只是在模块的方法解析链中添加了对模块的引用 - 但这种行为与此不一致。
有谁能告诉我幕后实际做了什么,以及如何扭转这种情况?
答案 0 :(得分:6)
因为看起来你可能想要在实例而不是整个类上完成这些,所以我会稍微更改klochner的代码来处理一个实例而不是所有类的实例。
module ModuleRemover
def remove_module(mod, options = {})
metaclass = class << self; self end
mod.instance_methods.each {|method_name| metaclass.class_eval { undef_method(method_name.to_sym) }}
end
end
正如Mladen指出的那样,避免删除在宿主类上覆盖的方法会很酷,因此这种方法的[only, exclude]
选项将是理想的。
>> c1 = C.new
>> c1.foo
=> fooing
>> c1.extend(ModuleRemover)
>> c1.remove_module(Mod)
>> c1.foo
=> NoMethodError: undefined method `foo' for #< C:0x11b0d90>
>> c2 = C.new
>> c2.foo
=> fooing
答案 1 :(得分:4)
module Mod
def foo
puts "fooing"
end
end
class C
include Mod
def self.remove_module(m)
m.instance_methods.each{|m| undef_method(m)}
end
end
>> c = C.new
>> c.foo
fooing
>> C.remove_module(Mod)
=> ["foo"]
>> c.foo
NoMethodError: undefined method `foo' for #< C:0x11b0d90>
答案 2 :(得分:3)
我不确定你要完成什么,但也许不是使用include
来添加实例方法,你想要做的是使用extend
将方法添加到特定实例该类,那么你不需要删除它们。
More information on the difference between include
and extend
答案 3 :(得分:0)