From: Logan Capaldo Date: 2006-03-11T02:01:03+09:00 Subject: Re: unextend ? On Mar 10, 2006, at 8:42 AM, Ross Bamford wrote: > On Fri, 2006-03-10 at 01:03 +0900, Dirk van Deun wrote: >> A very short and simple question: is there a function to >> "unextend" an >> object ? > > Might this suffice? > > class Object > def unextend(mod) > (mod.instance_methods + > mod.private_instance_methods + > mod.protected_instance_methods).uniq.each do |m| > instance_eval "undef #{m}" > end > end > end > > class A > def each; yield 1; end > end > > a = A.new > > a.extend(Enumerable) > puts a.map { |e| e + 1 } > # => 2 > > a.unextend(Enumerable) > puts a.map { |e| e + 1 } > # => -:17: undefined method `map' for # (NoMethodError) > > -- > Ross Bamford - rosco@roscopeco.REMOVE.co.uk > > I get the feeling that could be dangerous. Since you do it in the context of Object, you may very well delete methods implemented by the object that have the same names as ones in the module. One example I can think of is to_a. There is an Enumerable#to_a which which gives an array after iterating thru an object. Likewise there's an Array#to_a. That method, in object instance_eval'ed the way you have would delete Array's to_a all together. Of course #extend'ing an object apparently overwrittes the old methods anyway (as opposed to including it in the class, which inserts the module into the inheritance chain). At least with my hack when you don't loose method's you've specifically implemented yourself.