Hooks, aspect-oriented programming, and design by contract

Phillip J. Eby pje at telecommunity.com
Sun Jan 27 05:08:34 CET 2002

In article <pan.2002. at club-internet.fr>, 
pedro_rodriguez at club-internet.fr says...
> I checked those docs and I have got some remarks/questions about it :
> - What is the current status of TransWarp ? Will this part of Zope 3 ?

It is an effort entirely independent of Zope, basically my personal Grail 
Quest of sorts.  :)

As for the status, I'm in the midst of refactoring to make AspectJ-style 
pointcuts and advice possible.  It's almost done.

> - I get the impression that it got it the wrong way with Aspects :
>   + an Aspect (Template) -> creates -> a Component (Class)
>   + a Component (Class) -> creates -> a ComponentInstance (object)

In AspectJ, aspects are effectively added to a class hierarchy, but the 
class hierarchy is not considered an Aspect.  In TW, it's orthogonal and 
the class hierarchy is an aspect, too.  It's as though in AspectJ you 
wrote all the "main" class hierarchy using method introductions, and thus 
everything was an aspect.  I saw no reason to pick an arbitrary aspect 
and single it out as the "class hierarchy".

>   Maybe this comes from the influence of AspectJ doc readings but
>   aspect concept should be orthogonal to class hierarchy and not mixed 
>   in this way. 

One of the design difficulties I had was defining what the scope of 
aspects should be.  Many AOP tools assume that the environment of an 
aspect-oriented construction is an entire program, i.e. the entire 
language runtime environment.  I didn't want to require such a global 
"weave" environment, because to my mind it would hamper reusability, and 
an explicit goal of TransWarp is to facilitate reusability of components 
created by other developers.

If I want to use component X two different ways in my application, I 
would like to be able to add different aspects to each usage.  But if the 
scope of aspect weaving is global, I can only end up with one "copy" of 
X.  (Note that if X is a class, I could use inheritance and create two 
versions, then aspectize each, but if X is a family of classes, 
inheritance may become impossible.)  Thus, I chose to have the TW build 
process construct a family of related classes, which can be used 
independently of any other class or family thereof.  (It seemed to me, 
also, that this was an appropriately Pythonic way of doing it.)

> - In fact there is no more class hierarchy as we know it currently.
>   It defines its own hierarchy with aspects. Must be missing something
>   there, like : why is Aspect3 = (Aspect1+Aspect2)(...) better than
>   class Aspect3(Aspect1, Aspect2): ...

That's an implementation-specific thing.  I have in fact deprecated 
aspect inheritance and indeed the term "aspect" in TransWarp.  What TW 
does is provide a "build process" which can be used to create entire 
families of classes and or instances from meta-level specifications.  
Those specifications can be layered together to create more complex 
specifications.  One layer might define method wrappers for methods
defined in another layer, for example.  Thus, TW provides the tools and 
environment for doing AOP, but it is not inherently AOP in nature.

The bulk of the things I use it for are actually more for generating 
various things from metadata, and assembling components to construct 
applications.  Originally, I thought it would be more AOP-oriented, and 
the early versions had built-in notions of aspects which have since 
vanished from the code.

TW is really more of a generalized concept of building software 
components from specifications.  It just so happens that AOP is one of 
the things you can do with it.  However, I *have* just got through adding 
the notion of "advisors" this week (on a CVS branch), which at some point 
will become the basis for AspectJ-style "advice".  However, if someone 
doesn't like the way I implement "advice", they are free to write their 
own advisors that implement advice differently.  It's a microkernel sort 
of approach; as long as your "advisor" objects implement the interface 
needed by the build framework, they can inform, modify, and postprocess 
methods, classes, etc. as they are built.  This can include bytecode 
rewriting, if you're so inclined.

The thing TW has over writing extensions to the compiler package is that 
compiler extensions from different people aren't (generally speaking) 
usable against the same code base.  But Advisor, Specification, and 
Interpreter objects for TW can be implemented by different parties and 
still participate in the same build process.

> - TransWarp looks to be defining metaclasses and I got the feeling that
>   metaclasses can provide some helper methods to aspects, but are not
>   required.

TW uses metaclasses for specifications, but it's pretty much transparent 
to the user.  The metaclass instances get turned back into "real" classes 
(or ExtensionClasses, or even other metaclass instances) during the build 
process.  The metaclass instance form can be more flexible than a "real" 
class, but whether you use a real class or a metaclass instance, TW 
interprets it in more or less the same way. 

More information about the Python-list mailing list