Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: "Humane Pointcut Languages" [Was: Re: [aspectj-users] AW:Pointcuton a constructor with a custom @Annotation]

Gregor Kiczales wrote:
Hmmm...

Reminds me of http://www.charlespetzold.com/etc/CSAML.html
Ouch! ;)
More productively, I think the concision of the pointcut language is a plus;
but I can imagine some nice tool support that you could hover the mouse over
and see an elaboration of the pointcut.
I believe Adrian wrote such a tool, as an experiment (?).

I vacillate on this point, I'll admit. I've been doing some Ruby programming recently and it's given me a fresh perspective after having been in the Java "sphere" for so long. Rubyists are really into DSLs, because Ruby facilitates some limited, but useful, DSL capabilities (not to the extent of languages like Lisp or Meta Programming Systems, e.g., http://www.sergeydmitriev.com/blog/archives/2005/06/early_access_to.html, etc., but I digress...). Another influence for me are APIs like mocking libraries. Consider this example adapted from a unit test on a recent Ruby project (names changed to protect the innocent...):

FlexMock.use('foo') do | foo | # create a mock object and pass it as "foo" to a block foo.should_receive(:password=).with("password").and_return(nil).once # here's the first line of the block...
           foo.should_receive(:user=).with("user").and_return(nil).once
foo.should_receive(:do_something).with("-se", "#{arg1}").and_return(expected_results).once
           ...
           foo.should_receive(:logout)
       end

The mock is told what calls to value assignment methods (e.g., "user=") and other method calls to expect. If it doesn't get them, the test will fail later on. JMock syntax is very similar. While verbose, the fact that it much like regular English is appealing because it's self-documenting and straightforward to comprehend.

So here's what a similar "humane DSL" could look like for our example pointcut:

pointcut ctorCallInAnnotatedClass (Object obj):
call(constructors().takingAnyArgs().inClassesAnnotatedWith(MyAnnotation.class)) && bindNewlyConstructedObjectTo(obj);

I made this up on the fly. Certainly it could be improved. Of course the expert might get sick of all this typing and prefer the terse syntax. The self-documenting quality is a real advantage for real-world projects, both to minimize the need for support documentation (there is little need to write a comment explaining this pointcut) and to make it easier for other team members and AOP neophytes to comprehend the code. Again, most code is write once, read many...

Actually, the main reason I've been thinking about this lately is not so much to solve the terseness issue in our current example, but to think about higher-level AOP abstractions. It bothers me that we talk about Security as an aspect (for example), then turn around and write PCDs that reference specific join points in specific classes, methods, etc. in our applications. We're mixing levels of abstraction and that causes many of the practical issues people wrestle with, IMHO.

Of course, the recent work on interface-based AOP is a huge step forward. I think it would help us a lot to be able to write our PCDs and maybe the AO interfaces themselves in appropriate DSLs, if not DSLs for the concern domains (e.g., security), then at least a DSL that's more natural for "cross-cutting concerns", in general.

dean
-----Original Message-----
From: aspectj-users-bounces@xxxxxxxxxxx [mailto:aspectj-users-bounces@xxxxxxxxxxx] On Behalf Of Ron Bodkin
Sent: Thursday, April 20, 2006 2:46 PM
To: aspectj-users@xxxxxxxxxxx
Subject: RE: "Humane Pointcut Languages" [Was: Re: [aspectj-users] AW:Pointcuton a constructor with a custom @Annotation]

I agree completely. I've often said that AspectJ's pointcuts and type patterns need a long form, rather like xpath has a long, functional style one in addition to its dense, compact, and cryptic version, e.g., //title is short for /self::node()/descendant-or-self::node()/child::title (in a simple case, the short form is clearer, unsurprisingly!)

I could see a more functional non-positional syntax, e.g.,

signature annotatedConstructor : member-annotation(@MyAnnotation) &&
static-type(*) && method-name(new) && static-arguments(..);

pointcut callAnnotated() : call(annotatedConstructor);

-----Original Message-----
From: aspectj-users-bounces@xxxxxxxxxxx
[mailto:aspectj-users-bounces@xxxxxxxxxxx] On Behalf Of Dean Wampler
Sent: Thursday, April 20, 2006 2:04 PM
To: aspectj-users@xxxxxxxxxxx
Subject: "Humane Pointcut Languages" [Was: Re: [aspectj-users] AW:
Pointcuton a constructor with a custom @Annotation]

Ron Bodkin wrote:
Dean, I think you mean call( @MyAnnotation *.new(..) ) (or just call(@MyAnnotation new(..))), since there's no return type for a constructor.
...
Yes, I forgot about the extra "*" for the (invalid) return type that was in the expression. Need to get my glasses checked, I guess ;)

I've made mistakes like this occasionally in my own PC definitions (PCDs). The PCD language is very "dense" and requires careful inspection of any PC. Given a lot of recent discussion in the bloggosphere about "humane interfaces" (e.g., http://www.martinfowler.com/bliki/HumaneInterface.html), it would be interesting to consider a more verbose & humane PC language for AspectJ that could be used with the existing language. When you consider that a typical PCD, like most code, is written once and potential read many times, I would certainly use a more verbose language if it were available.

For example, Perl has more human-readable equivalents to its many cryptic "$..." variables. What if AspectJ's PC language had special symbols like the following:

$any_return       => "*" used for the return type
$any_arg           => "*" for any single method argument
$any_arglist       => ".."

etc.

Just a thought...

dean
_______________________________________________



Back to the top