From: "T. Onoma" Date: 2003-12-05T08:58:27+09:00 Subject: Re: Underpinnings of Method Wrapping On Wednesday 03 December 2003 03:21 am, Peter wrote: > We've got a lot on the table, but we still have got lots of sorting out to > do I think. Also I have the feeling we've almost run in a circle, but it > doesn't feel like a lost effort. Hi Peter, Hope your week has gone well. The couple of days off has helped me clearify some things. Indeed, I've been doing a good bit of work on my project Baker and it is becoming increasing clear how AOP ideas could be put to good use there. Moreover, it's becoming clear where Ruby prevents me from doing any such thing, or at least makes it difficult. So here's the overall conception that's developing in my mind: Given a class/ object there are three ways to augment it. For lack of more better terms I'll call these: subclass, redefine and superclass. In Ruby we do these in quite a number of very different ways, for example: subclassing on a class: # B is the subclass of A class B < A ... end subclassing on an specific object: # an anonymous singleton (sub)class class << a ... end # as above but for one particular method def a.ameth ... end # extending an object with a module a.extend(B) redefining on a class: # repeat class statement class A def x ... end class A def x ... end # class eval A.class_eval ... # for a specific method A.define_method ... superclassing on a class: # A is the superclass of B class B < A ... end # module mixins class B include A end And I'm sure the are other ways I haven't considered. What this boils down to, if one were to generalize it completely is a means to do all three: subclass, redefine and superclass, either explicitly, giving a new name to the altered entity, or inplace (implicit/anonymous), and with any number of subclass/superclass layers. Finding a very consitent means of doing all this and also adding the extra features for AOP generics, like indicators, while yet remaining as close to current Ruby as possible, is the real trick. So where do wraps fit into this? You've probably already guessed from my previosu use of the term submethod: they are forms of subclassings. So let me try to say this in another way. Here is a list of the different possibilities I mention from above with one example for each of how it can be currently done. In the following list 'class define' means to define it for an entire class, so that all objects of that class will inherit the behavior. 'obj define' means define it only for a particular object. class define explict subclass: class B < A class define implicit subclass: don't have class redefine explict: B = A.dup; B.class_eval ... class redefine implicit: class A; class A class define explicit superclass: class A < B ... include Mixin class define implicit superclass: A.class_eval {include Mixin} obj define explict subclass: b=a.dup; b.extend(B) (limited to 1 layer) obj define implicit subclass: a.extend(B) (limited to 1 layer) obj redefine explict (don't have, simulate w/ dup; singleton no super) obj redefine implicit (don't have, simulate w/ singleton no super) obj define explicit superclass (don't have) obj define implicit superclass (don't have) Of course there may be ways to do some of these that I am unaware. Also I fail to mention the opposite destruction of these, i.e. undefining a method. Aside to this, is the related fact that if you define a class and then create an object of that class, and then subsequently implicitly redefine the class, the object will also be changed. This can be useful, but also the opposite, and it might be nice to have a way to "freeze in" an objects class definition. But I digress... I know this is somewhat confusing. It is hard to find the right words. I find myself wanting to draw pictures. I think the simplist way to think about it is: given a class with a method, how do I wish to augment it in relation to the super call? Do I want my augmentation's super call to access the given class' method; or do I want the given class' method's super call to access my augmentation; or do I want to replace the method altogether? Do I want an explict new class/object or can I just augment inplace. Then take this and apply it to outside programmers who might want to do the same to this code, and then someone else wanting to do it to their code. And so on. Pulling it all together we can draw a complete picture. Hope I've managed to explain this well enough. Its harder than I tought. :-) -t0