Aspect Oriented Programming


VisualWorks

On this page we describe some simple experiments in augmenting VisualWorks with AOP concepts. The example on this page illustrates a few key concepts. Class "AspectTest" is a simple class with some instance / initialization methods, and a method "run" called by three methods, "run1", "run2" and "runWithException" respectively.

The first goal of this example is to add logging to the" run" method, but only when called from within the "run1" method. The logging is handled by an instance of class "SomeAspect". Method "logRun" introduces a new fragment for the logging (tracing) aspect. The fragment specifies that we want to generate logging contents before executing the "run" method.

The pragma directive specifies the aspect (name), the aspect type and the base method (instance or class) we want to intercept. Note that extending the implementation to deal with e.g. pattern definitions of methods is rather straightforward.

The actual aspect code follows the pragma directive. An important point to note here is that logging will only be performed when the "enabled" flag is set. This flag is an instance variable of the aspect, and is shared by all methods of the logger aspect.

Class method "new" specifies that whenever a new instance of the base class is created, we instantiate the logger class and "merge" the logger instance with the base instance. All subsequent applications of logger aspects on the base object will be handled by the same logger aspect.

Now we are ready to introduce the logging enabling aspect method "enableRun1Log". This method surrounds execution of base method "run1" with code to enable / disable the enablement flag. Note that we could replace this aspect method with two distinct before / after aspect methods.

In the first run sample we execute methods "run1" and "run2" alternatively. Only the executions of "run" within the context of "run1" are effectively logged.

Base class method ""runWithException" also calls "run", but generates a "SubscriptOutOfBoundsError". Aspect fragment "proceedRunWithException" illustrates exception handling, and in this case, how we proceed the base code. The second run example returns the expected result "#run", since despite the original exception, method "run" is effecively called.

When the compiler encounters the aspect pragma directive, it creates an aspect fragment and registers it in the aspect fragment repository. Upon accepting a method for regular base classes, the repository is consulted and the necessary method wrappers are instantiated.

When adding a new type of aspect, a new method wrapper class is required. A simple factory design retrieves the appropriate wrapper class for each aspect type.

To implement the FbyAspectWrapper class, we added method "fby:" to class "BlockClosure", and implemented the "valueWithReceiver:arguments:" method as shown above. Class "FbyMessage" implements "evalAspect:" in a straigtforward way. Returning the appropriate wrapper aspect type finished the job.