如何反转ruby的include函数

我将在代码中解释我正在寻找的内容,因为这可能是最简洁的:

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只是将模块的引用添加到类的方法解析链中 – 但是这种行为与此不一致。

任何人都可以告诉我幕后实际做了什么,以及如何扭转这种情况?

 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> 

因为看起来你可能想要在实例而不是整个类上完成这些,所以我会稍微更改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 

我不确定你要完成什么,但也许不是使用include来添加实例方法,你想要做的是使用extend来只为类的特定实例添加方法,那么你就不需要了删除它们。

有关includeextend之间区别的更多信息

几年前,我使用了gem的邪恶 ,不包括模块等,但显然它已不再维护。 所以我只是尝试了un (仅限于我的旧ruby 1.8.7)。 如宣传的那样工作得很好:

描述:

un提供了无意义和不包含的内容,以允许更好的面向原型的编程体验。

如果你替换你的“#some magic here”(安装un之后)

 require 'un' Whatever.uninclude Mixin 

你得到了你所描述的行为 – 差不多。 Object已经有一个名为method的方法,因此您会得到“错误的参数数量”错误。

如果有人在ruby 1.9或jruby上尝试它并报告结果(我为此制作答案社区维基)会很好。