> Well, I thought of using the underscores to allow one to indent as needed to
> line up the first and the last end with the rest of the code. But now I see
> that it is really a problem since the interpretor would have to depend on
> that indentation (or number of underscores) to make sense of it, which is
> yuk.

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.

> But I did notice that if I switch to four spaces for indention (rather
> than the two spaces I normally use) this, in fact, works:
>
>   class X
>       def whatever
>           if something
>               # ...
>   end end end
>
> Too bad I don't like four space indentions ;)

Me neither. I know some people that do though.

> What I don't like about a seperate mechinism is A) it will be essentially the
> same kind of mechinism, so you have two separate components of ruby doing
> essentially the same things. B) You now have to mange these two compenents
> separately and take into account all the considerations in which they may
> interact and/or conflict. C) Under the hood it looks pretty much the same:
> adding a wrap is adding an anonymous subclass of some sort and linking it
> into the class. And D) a seperate mechinism means much more code refactoring
> of the interpretor, more code, more overhead, and consequently more potential
> for bugs.
>
> One might argure that there's something wrong with singletons being able to
> have there own singletons (i.e. meta-singletons), but I don;t see what that
> would be since, as long as one can still undef/redef the singleton layers as
> a whole (which one can), then meta-singletons are a complete logical superset
> on regular singletons.

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.

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.

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.

> 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

> 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.

> I think the main differences in our appraoches, please correct me if I'm
> wrong, is that you're coming at it with a more formal understanding derived
> from AspectJ, while I'm coming at it more from having implemented wraps by
> hacking at Ruby. This is good, b/c it means we are attacking it from both
> ends.

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.

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.

> :) It actually looks harder than it is. What makes it so ugly is having to use
> ___method___ to (hopefully) circumvent name clashes. If I remember correctly
> it essentially wraps every method of a class to which #when has been applied,
> or in the case of #bind, every single method of a class in order to hook on
> instance variable changes. I can give you an end result example of a GUI wrap
> if you'd like.

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! And the syntax is fine, easy enough to go back and make syntactical
> modifications when need be.

True. :-)

Peter