From: Peter Date: 2003-11-30T09:01:55+09:00 Subject: Re: Underpinnings of Method Wrapping > The join-points are the only thing required to facilitate all of this. So I > did not think it neccessary to elaborate on. I will go back a mention it > though. Just to be clear, the method I used with "Ruby's dynamism" provides > pointcuts. Its not that Java has pointcuts and Ruby doesn't. Only that Ruby > doesn't need special syntax to do pointcuts (in fact it probably would be > more limited even if it did). Oh, I agree completely, Ruby will be able to specify the most general pointcuts possible since you can specify it in code. Any code. Wildcards is limiting. Though maybe I should mention that the AspectJ guys said nobody ever missed anything more general then wildcards in AspectJ. > Not exactly, they can be both, and the whole spectrum inbetween. This is a > tough question. Take for instance a common form of doing very simple > plug-ins: subclassing. When you make a subclass you'll redefine some methods > to get the new behavior desired. When you do this, if the wrappers in the > superclass in any way effect function, then "99 times out of 100" the > wrappers will have to go. But if they're just to observe, like logging, then > you may still want them, you may not. In the end, I think we really need to > support both scenarios. My problem though, is that most people only see the > logging abilities of AOP, and don't realize there's much much more you can do > with it, so they think, "of course keep the wrappers", but when you really > start to take advantage of AOP's power to do more than this, that's when > you'll start thinking, "why do I have to keep flushing these wrappers!". > Moreover, not flushing them by default, will only promote the idea that AOP > is only good for logging type applications. So I think it much better to > flush by default --we can still offer "table clothing" with a simple extra > keyword. I agree we should support both scenarios. But I don't agree yet on discarding wrappers by default. Aspects are supposed to model orhtogonal aspects of an application and are supposed to be uncoupled. Which means wrapper and wrappee ought to be uncoupled. But maybe that's one of those cool ideas that are infeasible in practice. And the use of method combination may not be limited to AOP... > This reminds me of an RCR I put in once. I suggested that every object have a > keyword reference back to its "brith parent". So if I cerated object foo = > Foo.new from within object bar, foo#parent would reference bar. In this case > it seems their might be good reason for each method to have a keyword method > (Method#cflow) referenceing the method object it was called from. In that way > I think we could offer cflow support. Yes, except that Method#cflow will only allow looking back one step in the calling stack. In AspectJ, cflow looks back along the complete calling stack, which is quite expensive to do if you'd use a Method#cflow for looking at the calling method. Actually AspectJ's implementation can be done in Ruby using only wraps as follows: def foo # ... end def foo oldInFooCFlow = $inFooCFlow $inFooCFlow = true super $inFooCFlow = oldInFooCFlow end def bar # ... end def bar if $inFooCFlow # advice added to bar in the cflow of foo end super if $inFooCFlow # advice added to bar in the cflow of foo end end I used your RCR syntax. And forgive me the use of the global var, but that least clutters the point. So it is possible foo calls some foo2, which calls some foo3, ... until eventually bar is called, and it will work without the need for looking all the way back up the call stack. As for the use of the global variable, in AspectJ this is easily done. Every aspect in AspectJ is a singleton, with its own data members, and all the advice from that aspect (read: wraps) can access these data members. As such it effectively provides global, yet private variables. > I think a lot of this is pointing to the simple fact that Ruby needs to make > its Methods more capable and introspective, much in the same way that > classes/objects are. For instance, cflow, and my suggestion for built-in > keywords for args, keys and block, plus a way to see what class/module the > method is in (from the inside out, we can already do from the outside in), > and so on. Having such capabilities helps exploit the full potential of AOP. Agreed. > I cann see it to some degree: off the top of my head: If the method #kill was > called from method #hunt, then you might want to trigger the method > #excitement, but if the same method #kill was called from #protect_thyself, > then it should instead trigger #relief. Very abstract, but I think it paints > the proper idea. I understand. It offers a way to find out about the callers of a method - or more abstract: the context of a call. Though the abstract idea sounds mighty interesting, I'm not so crazy about using method names to find out about the context. But I don't know about a better way. Just weird that you have to name your method in a particular way to get the right behavior from a method you're calling. Peter > P.S. So what did you think of the singleton foundation? Are you referring to the line "wraps act very much like singletons" from your RCR? In that case, I think I missed the point. But that's probably because it was the explanation to something that's so obvious to me :-)