Getting rid of metaclasses (Was: Behaviors vs Modules)

Jim Benson jb at speed.net
Thu Feb 28 17:31:39 UTC 2002


Robert,

I've used it for simple tasks. Here's one way that I've used it as you've
described:

I wrote a video-editing type of application which looked suspiciously like
iMovie. I tried to emulate a typical desktop with dialog boxes, a tool bar
and pull down menus.

Morphic has built in 'layering', that is, you can set the z-order of a morph
by setting it's #morphicLayerNumber property. However, the PasteUpMorphs
don't really honor that in the course of things when you add/remove morphs,
so your system widgets tend to get written over and things are not pretty.

There are a couple of solutions to this. I could subclass PasteUpMorph into
a "DesktopMorph" with all of it's attendant trappings. However, that type of
implementation isn't very pretty as you have to reach further into the
system code (and have a lot more system knowledge to do something which
should be trivial) than necessary. I could be really careful about how I
insert morphs onto my desktop, by substituting different addMorph type of
calls for the normal ones (that's not in my nature ;-)

Or I could just let the machine do the work. Really, I only wanted to
transform a couple of PasteUpMethods methods such as (conceptual code):

PasteUpMorph>>addMorph: aMorph
 self addMorphInLayer: aMorph.

to make them honor the morphic layering. Of course with your SAspect code
this was easy. When I entered a video project, I would tell the project to
install the appropriate aspect to make the PasteUpMorph morph (world) behave
the way I wanted. When I left the project, I removed the aspect, which
returned the image to stock behavior. This is all part of the MethodWrappers
concept. This is all second nature to me, having patched many interrupt
traps before.

In the Smalltalk world this is a very subtle nuance (like a 16 ton weight).
I've redefined a methods behavior, not by overriding it or recompiling it as
one would traditionally do, but by shaping it after it has been defined.
This is also a different concept than having 'pluggable' behaviors, where
one would store a method or block context for execution into an ivar and
then substitute a different block of code into that ivar.

Of course, this is crucial to the modules code. I've been following the
modules discussion here, but here's my fundamental concern: How do I end up
not programming on quicksand? From what I understand so far, the modules
solution is about keeping different chunks of code and data in a seperate
space that you can 'swap' in. I can see how that works if the module is
independent and does not change the 'base' image code. Where I get lost at
is how all the modules interact when they fly back into the image, and start
changing that base code, potentially over writing each others changes. If
you don't have a stable base, and some protocol saying how you can attach
changes onto that base, it turns to quicksand real quick.

I haven't looked very deeply into the weaving parts yet, though I think I
have a good application for it in the area of autonomous characters. This is
obviously the interesting area of your work. What type of applications have
you been using it for?

Jim

> Thanks, Jim.
>
> Have you tried to use AspectS for other tasks than debugging?
>
> With AspectS you can change the behavior of the system not only at
> the level of classes, but also from the point of view of a
> subset of specific instances, either senders or receivers of
> a certain message, or both...
>
> Best,
> -Robert
>




More information about the Squeak-dev mailing list