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.
How would they know? 
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…
I’m had some varying thoughts on this. But I think I’ve come to a good
solution. First let me point out that, although unmentioned in my RCR, I’m
all for pre and post, and actually, I’m now in favor of dblack’s suggestion
of simply using pre and post as keywords [yes, db, bygones &c.] b/c they are
ONLY for “meta-tasks” and can’t get invovled in the underlying exectution; so
in this manner they are quite distinct from def. In other words, defs “get in
line” while pres and posts “hang about”, if you take my meaning. In light of
this, it seems appropriate for redef to flush the wrap stack, but all pre’s
and post’s still remain. So we have proper seperation of these concerns: pre
and post for extrinsic, def wrap for intrinsic.
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.
Is it very expensive? ameth.cflow.cflow… hmmm, I guess your right, if your
looking for a method that could be anywhere up the reference list. Although I
think in practice the list will only get so long. (And shortcutted for
recursive calls). But I definitely see your point (though I think
Method#cflow would still have its uses).
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.
I noticed right away that you were using my syntax
I’ve heard so many
people say how ridiculous such a syntax is (funny that they keep mentioning
it), but right now I can tell you it feels completely natural --seeing the
defs come in order parallels their stacking order. Anyway…
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.
Definitely, and I’m certain we can achieve the same thing with module’s and
their instance variables. Define a module containing aspect methods and the
module variables they need and apply as desired. Hell, we can even wrap the
aspect methods!
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.
Have to add to RCR.
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.
Ah…but this is what the indicators are for.
def eat:eating
end
def gorge:eating
end
def stuffyourface:eating
end
We can aspect all the eating methods. ( no, i’m not hungry 
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 
I really need to go back and specify this. It was still a little fuzzy in my
mind when I started the RCR, but now it’s quite clear --perfectly clear. So
much so that I pulled up the Ruby source and hacked it in. Changed about 6
lines of code and got it working, albiet it still needs TLC to fix-up and add
all the bells and whistles, but the proof is in pudding, and I got pudding.
But I’m getting ahead of myself. I need to explain the point. Lets take this
example:
class Classic
def x
print “X”
end
end
c = Classic.new
def c.x
print “(”
super
print “)”
end
c.x; puts # => (X)
We have created an object c, that has a method x, then we defined a singleton
also called x. The singleton effectively wraps the original method. This is
explained well in the Pickaxe. Check out page 246, Fig. 19.3. The diagram is
describe a couple pages back under Object-Specific Class; or you can surf
here:
http://www.rubycentral.com/book/classes.html
So then what happens if we try to add another singleton of the same name?
def c.x
print “[”
super
print “]”
end
c.x; puts # =>
Why didn’t it wrap again? Let me quote the end of that Pickaxe section:
“Ruby performs a slight optimization with these singleton classes. If an
object’s klass reference already points to a singleton class, a new one will
not be created.”
Obviously when Matz created this, it didn’t occur to him that unlimted
wrapping may be useful. He just saw that it was wasted overhead to have a
separate singleton class for each and every singleton method. But his
optimization had the above side effect --you can only define one layer. So I
went back and changed the optimization such that when a method of the same
name already exists in the singleton class, a new singleton class (metaclass
in the code) is created. So my version of Ruby instead does the following:
def c.x
print “[”
super
print “]”
end
c.x; puts # => [(X)]
That’s all there was to it, and it serves as the perfect starting point/basis
for building all the rest of the AOP features.
-t0
···
On Sunday 30 November 2003 01:01 am, Peter wrote: