|
Method Wrappers can add hidden behavior to a method without
recompiling it. They can be used to change a method's behavior. Commonly, they
are used to add behavior before and after the default method executes. For
example, we can create a coverage tool by using a method wrapper that increments
a counter when it is called. If you would like more detailed information about
method wrappers, you can read the ECOOP'98 paper
Wrappers to the Rescue.
WARNING: Incorrectly using the wrappers can crash your
image, so you should save your image before using them. Most problems occur as a
result of installing them on methods that are called either in the
beforeMethod or
afterMethod which results in infinite recursion.
|
|
User instructions:
To install the method wrappers, simply parcel-in the MethodWrapperBase.pcl
file from
MethodWrappers.zip into a VisualWorks image. The other files
can be parceled-in in any order or not at all. Both the Synchronization Wrappers
and the Method Wrapper Example parcels have examples of specialized method
wrappers. The Synchronization Wrappers can be used to synchronize messages on an
object. Once loaded you can send the #synchronize messages to any object to
synchronize all messages to that object. The other two parcels,
Coverage Tool
and
Interaction Diagram, have their own pages
of documentation.
To use a method wrapper,
send the class an
on:inClass:
message to the class of the method wrapper you want to create. The first
argument is the selector for the method, and the second is the class that
defines the method. This returns a new method wrapper which can then be
installed the by sending the install message and uninstalled by
sending uninstall message.
To create a new type of method wrapper, you must create a
subclass of MethodWrapper and redefine the
beforeMethod
and/or afterMethod to add your specific behavior for the wrapper.
If you only need to redefine the
beforeMethod, you can redefine the
valueFrom:arguments: method instead (see the
CountMethodWrapper). This is somewhat faster since it doesn't need to
create two blocks and send the valueNowOrOnUnwindDo: message.
Bugs/Limitations:
-
If you recompile a method that has a method wrapper, the wrapper will not
be installed on the new method. This behavior can be changed by modifying a
couple of methods in class Behavior, but this seemed like the best idea.
Note: when you add or remove an instance variable from a
class, the class must recompile all methods associated with the class, so it
will lose all wrappers.
-
You cannot view the decompiled source code of a wrapper method. Since the
wrapper method refers to itself, it will go into an infinite loop trying to
generate the decompiled source.
|