From: Trans Date: 2008-11-15T11:28:37+09:00 Subject: Re: Overriding methods in a class using a mixin On Nov 14, 5:02 pm, "James Coglan" wrote: > Hi list, > I just had this idea and thought I'd share it in case someone can improve > upon it, make it more robust. Basically, I've run into a situation a few > times where I want to override methods in a class but retain access to old > implementations, the sort of thing people like to use alias_method_chain > for. I tend to favour this approach, though: > > class Foo >   meth = instance_method(:foo) >   define_method(:foo) do |some, args| >     result = meth.bind(self).call(some, args) >     # do extra stuff... >   end > end > > But, then you've lost the old implementation: it's hidden in the closure and > you can't get another reference to it from anywhere else. So, I've come up > with a way in which you can copy the class's methods into a module, include > that module (making it part of the inheritance chain) and then mix other > modules in. Later modules can thereby override the class's own methods and > use 'super' to refer to them. This lets you insert code between an existing > class and all its subclasses, which can be useful. > > Code on github, with an example:http://gist.github.com/25104 Well done. I've explored a number of approaches to this is a pretty good one. On the downside though the reoccurring binding is going to slow things down. Anther approach is to override #new and #extend the object with the "aspect" module upon creation. > Comments, suggestions, and accusations of idiocy all very much welcome. > Expanding from this, I'd like to figure out how I can insert modules at > arbitrary points in the inheritance chain, rather than just using 'include' > to come between a module and it's last included module. You can just include it in the ancestor you want it to go after. But of course that's going to effect all subclasses of that class. Facets definition of Kernel#at() might interest you though. T.