I'll explain what i'm looking for in code as thats probably the most succinct:
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
I had tried just undefining the Mixin module using remove_const, but this doesn't seem to make any difference to Whatever. I had assumed that #include just added a reference to the module into the class's method resolution chain - but this behaviour doesn't agree with that.
Can anyone tell me what include actually does behind the scenes, and how to reverse this?
As it seems probably you want to accomplish these on instances instead of the whole class, so I would change klochner's code a bit to handle just one instance instead of all the instances of a class.
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
As Mladen pointed out, it would be cool to avoid removing methods that are overwritten on the host class, so an [only, exclude]
options for this method would be ideal.
>> 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
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With