From: Ross Bamford Date: 2006-03-11T02:18:30+09:00 Subject: Re: unextend ? On Sat, 2006-03-11 at 02:01 +0900, Logan Capaldo wrote: > 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 > > > > I get the feeling that could be dangerous. Certainly. I think 'unextending' is bound to be so - I get the feeling this may be why it's not already implemented in Ruby :) > 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). Good point. > At least with my hack when you don't loose > method's you've specifically implemented yourself. But is that really a better place to be? You extend a module, override a method, then unextend (or whatever) get left with what looks like some of the module. It's probably pretty likely the new method depends on other methods from the module, and so is now broken. Not that I'm disagreeing with you, it's undoubtedly a dangerous thing to do in any situation. Fortunately, I'm not (yet) forced to include health warnings on my code ;) -- Ross Bamford - rosco@roscopeco.REMOVE.co.uk