From: "T. Onoma" Date: 2003-12-11T17:39:33+09:00 Subject: Re: Underpinnings of Method Wrapping On Thursday 11 December 2003 04:04 am, Peter wrote: > Ever programmed Haskell? There indentation is significant, and that kinda > sucks. And you can get it right when writing the first version of the > code, if you use no tabs, but changing code possibly changes indentation > and then you get a preview of hell. ``scratch scratch scratch``. Okay, that eliminates Haskell from the list :) > > Too bad I don't like four space indentions ;) > > Me neither. I know some people that do though. Some people...I tell you. Hey, I know! How about I put in an RCR for 'alias e end' class X def whatever if something # ... e e e Now that's progress! :)) > I think you just may have just changed my mind partway. What I do like is > the idea of layering wraps. E.g., a logging layer that contains all wraps > related to logging, a profiling layer that contains all wraps related to > profiling, a GUI layer that contains all callbacks to the GUI, etc. But > I'm wondering; do you plan to give explicit control over the singleton > layers? So you can take out a layer, place it back or redefine it. That > creates some nice possiblities. Oh, nice. And actually it can be easily done. We already have the ability to define a named layer of singleton via #extend. This actually creates a mixin on the singleton class. So the extending module remains a seperate entity from the singleton itself, and having a descernable name shoudl be fairly easy to manipulate/remove/replace. Good thinking, Peter! I like it. > My initial impression was BTW that for each wrap you'd add a singleton > class, and although I don't know the Ruby internals, my guess is that > would give overhead proportional to the number of singletons because for a > call to a method in the worst case you'd need to walk over the complete > chain of singleton classes. Definitely wouldn't want to scarfice optimization. A singleton layer only needs to be separate when it is explictly told to be so (i.e. extend) or when antoher method of the same name already exists in the default singleton, at which point it bumps up to a next layer, and thus acts as a wrap upon a wrap. > BTW, I don't know if you've changed your mind about this (my guess is you > haven't), but your idea was to just use def for wrapping, and have 'super' > call either a previous wrap or the method in a superclass (and that fits > nicely with singletons, I know). If you'd 'def' a method that does not > call 'super', you'd automatically have a redef. Only when you want to do a > redef with calling the method in the superclass that you'd need an extra > keyword 'redef'. But the one practical problem I see with that is the > issue of how to actually remove wraps that are redefined in the > implementation. You'd want to do that because if you have a very dynamic > application, say one that operates in a number of modes and that often > changes mode and that uses wraps to conveniently model the changing > behavior, then wraps will accumulate if you don't clean them up. But you > can't because you have no way of determining whether a method calls super > because of eval. Ah, I think I see what you're saying: If I just use def without a super, how is the interpretor to know that this amounts to a redef and therefore should drop the old wraps? So either we have to use redef on all occassions of redefinition, or have some sort of wrap gc. Such a gc could work by eliminating wraps that fail to execute after the execution of their corresponding method, but such gc adds additional overhead, which I don't like. Yet this also plays heavy into the fact of when and when not to eliminate wraps. Consider what happens if we use a separate keyword like def:wrap for defining wraps. If I first define a wrap and then add a second wrap, but this time with no super, we have the same difficulty, but also we now have something specifically called a wrap posing as the actual method! Moreover (and this applies to my notation as well) what if there is a way to redefine the outer most wrap layer, or even eliminate it. Would those "free floating" wraps now come back into play? It's funny that this comes up, b/c I have started to think, in the back of my mind, that inner wraps --and by that I specifically means wraps that are flushed with the redefinition of the core method, are really of less use than I had orginally thought. Certainly a tangle to unravel here. I pray you can shed some clarity on this. > > Unless, I'm misunderstanding you (and seeing that this a complex subject > > we know that is quite possible :) I'm not seeing how this would work. > > I think I see the problem... An aspect can access the internal state of > the classes it adds advice to. Generally that is OK because the underlying > system should be independent from the aspect, but not the other way around > (although that would be cool too, but there must be some linking one way > or the other). Also it depends on the kind of wrap. My feeling is that > inner wraps can freely access all variables in a class, outer wraps should > rather refrain from that to prevent tight linking. An exception is of > course when variables are part of the interface of the class and thus > deliberately exposed. > > What I meant though is that an aspect can have its own data, and those > data are private even if the aspect stores those data in another object > (because the data naturally belongs to that object, but managing that data > is the responsibility of the aspect). Actually the aspect controls the > access to the data, and can choose to make its data visible to everyone, > or just visible to itself, and anything in between if we'd think that'd be > necessary. Of course if we'd aspect and aspect, the former would be able > to see the latter's data too, etc. But maybe in practice this access > control is unnecessary Hmm... Not sure if I completely understand yet, but as far as I can at this point imagine, I can only really see data private to the aspect as module varaibles (or local instance variables when we get those), psuedo code: module MyAspect wrap somemethod @@myaspect_private_info = :testmode end end @@myaspect_private_info could have no effect on the class that this aspect is applied to even if it oddly had a class variable of the same name --at least I think it could work like that. Actually I'm not sure. Other wise I don't know how to go about it. > > Good idea, I'll put those terms in the RCR tonight, and work on ading > > indicators, since I think we both agree on the utility of those. Yes? > > Yes, definitely. Already started-in on it. Give me a day or two. I am facing one problem though. Our use of the words inner and outer, up til now, have been a bit loose, either meaning tightly-linked and loosely-linked, or meaning non-persistent and persistent upon redef, respectively. So I'm not sure in which manner I should to give them a specific definition. > I'm indeed coming at it from a different point than you, definitely. But > my point of attack is not so much "more formal understanding derived from > AspectJ". In my mind, AspectJ is *one* implementation of AOP. And it > contains many useful ideas, and those are easy to convey (well, mostly). > But although wraps are part of AspectJ, the use of wraps is not limited to > AOP. Wraps are also convenient in other places. But using wraps does not > ensure that you are doing AOP. Neither does doing AOP imply that you need > to use wraps. I never contested the use of wraps. I was just asking myself > (and you) the question whether inner wraps - or at least my interpretation > of it - are really AOP or that it is really just an OOP thing that's more > naturally done using wraps. Oh, that's interesting. How do you do AOP without wraps? I do see what you mean though. Certainly wraps can be used as merely a generic/implict means of subclassing. Something we can already in part do using singletons. I wonder how one defines AOP exactly then. Are you thinking that if a wrap becomes intrinsic that it is no longer AOP? Or does an advice have to cross-cut over more than a single method to be AOP? What if it does the former intrinsic behavior, but in fact cross-cuts across different methods and classes. Perhaps tricky but certainly possible. How does one draw the line? What the heck is this thing AOP we keep talking about anyway!? ;) > Actually I should tell you that my first contact with AOP had nothing to > do with wraps. The example I was presented was that of code optimization. > That's a really good example of a cross-cutting concern, but at a finer > granularity than method wrapping. It's a known fact that good design and > efficiency sometimes don't agree. And highly optimized code is very hard > to maintain (I have that problem currently at work, and I am forced to > create a new version that will be less efficient, but at least it will > be maintainable and debuggable). But AOP makes it possible to write nicely > designed code and describe the optimizations as aspects. Wow. Can you tell me more about how that works? That's sounds quite interseting. What level of granularity do you mean? How does it work? > No, it's not necessary. I still think a GUI is a really good example of > AOP, and I've got a pretty good idea what it will look like. And I thing I > know where the misunderstanding comes from, and I can content myself with > that for now. Great. Although I'm not sure I understood what the misunderstanding is/was. But just the same, I certainly think we have come along way toward common understanding. T.