[TransWarp] Re: Usage example of TransWarp?
Phillip J. Eby
pje at telecommunity.com
Fri Mar 1 15:20:35 EST 2002
At 01:23 PM 2/28/02 +0100, Luc Stepniewski wrote:
>I'm trying to understand how to use TW, but I can't find anything I could
>start with. Even the documentation is *disturbing* as it is absolutely not
>synced with the current version (still examples using the Aspect class
>which doesn't exists anymore :-(
I feel your pain, and I'm working on the documentation situation. See below.
>I'm interested in the aspect oriented programming parts of TW. Is it
>functionnal, and if yes, is the API stable (I mean will it change
>completely in 2 weeks for example :-).
The API is now lightweight enough that even if it does end up changing
slightly, the impact on code should be negligible. The most likely
changes, however, have to do with subtle semantics of name rebinding during
inheritance and weaving; specifically, there are some bugs/limitations I
need to fix! (The fixes shouldn't affect how you call the API, however.)
The only way there will be any significant change to the AOP API at this
point, is if I discover an issue that is not resolvable without changing
the API. That's because the API is now *so* simple that the only way I
could improve on it would be to get rid of it altogether!
>Could you give me/or point me to some examples of use (even very simple
>ones) of TW for the AOP?
The best place for AOP examples right now are in TransWarp itself, in the
non-AOP parts! The TW.Database package (e.g. DataModel and LDAPModel), the
TW.UML package (TW.UML.Model and TW.UML.MetaModel), and the TW.SEF package
all make explicit use of TW's AOP capabilities.
I have dramatically condensed the amount of code that you have to write in
order to do basic AOP techniques in TransWarp, at a slight expense in
flexibility, by introducing the concept of "module inheritance". Basically
module inheritance lets you treat modules as if they were classes, and have
one "inherit" from another, but the "inheritance" is aspectual, in that
classes and nested classes are merged by namespace, inheritance is rebound
by name, and functions or methods are wrapped around each other and can
call the "previous" definition using the special name '__proceed__'.
A simple example: TW.Database.DataModel defines several classes: Record,
RecordType, TypeManager, Database, and
SimpleTypeManager. TW.Database.LDAPModel declares its '__bases__' to be
'TW.Database.DataModel', meaning it wants to do "module inheritance" from
the DataModel module. The LDAPModel module, however, contains only partial
definitions of the classes 'Record' and 'RecordType'. The rest comes from
weaving in the contents of the DataModel module in almost the same way as
is described in the (outdated) documentation for aspects.
In other words, if you take most any of the old examples, and rewrite them
converting each "Aspect" class into a module, you should be able to get
pretty much the same results. To do the "aspect addition", you would
create a module which lists in its '__bases__' global, the modules you wish
Basic (but current!) documentation on the module inheritance process and
API can be found at:
Or you can read it, in plain text form, from the docstrings of the
TW.API.Modules module. :)
As you will see, doing AOP via module inheritance requires *far* less
coding overhead than the old-style API, as long as you don't mind placing
your aspects in separate modules. You need only define a '__bases__'
global (if applicable), and call 'TW.API.setupModule()' at the end of the
I am in the process of creating a TransWarp weblog site where I'll be
posting a series of articles over the next few months on various topics in
using TW. The new site will be replacing the TransWarp Wiki as the primary
source of information on TransWarp. I hope to have at least its home page
up and ready by next week, and will make an announcement on the TransWarp
mailing list when I've done so.
More information about the PEAK