ajh18 at cornell.edu
Sun May 4 04:23:03 UTC 2003
Here is my new behavior/module idea.
A Squid module defines static (class) variables, and both instance and
static (class) methods. A method is either public (exported) or
private, but all variables are private. A module also specifies a set
of imported modules. Local methods may call public methods of imported
modules. An imported module may be substituted with another if it has
the same method interface. Calls to imported methods are prefixed with
the imported module name if more than one imported module implements the
same method name. Otherwise the prefix is not needed, but the canonical
source listing will include all prefixes.
There are two kinds of modules: Behaviors and Classes. A class has
instance variables while a behavior does not. Also, only
behaviors can be imported into other modules (class or behavior).
Futhermore, all class methods (instance or static) are private unless it
overrides a behavior method.
When a message is sent to an object, a direct call is made to the named
method in the imported behavior that defines it. This method may send
other messages but may never access any receiver fields. If it sends
the classResponsibility message to the receiver the original message is
forwarded to the receiver's class invoking the class method that
overrides it. The class method may access fixed fields by instance
variable name or indexable fields by varAt: (inst var names are compiled
to calls to fieldAt:(put:) providing a hook for all field access).
If classResponsibility does not find an override method in the class and
error is raised. An alternative, classMayOverride, also delegates to
the receiver class but does not raise an error if not found. It just
falls through to the "default" code.
This independent behavior and class scheme allows flexible inheritance,
simple extension, and improved modularity. A class can "inherit" from
multiple behaviors just by implementing their classResponsibility
methods. A behavior can add benign class extensions to any class just
be defining the extension methods in its own behavior. The extension
methods can only access state of its receiver class by sending the
appropriate accessor messages. Having these extensions defined in the
same behavior that uses them improves modularity. Also, classes can
only override methods that are designated as classResponsibility or
classMayOverride, providing an explicit "subclass/polymorphic" interface
which also improves modularity.
One draw back is that every object will understand every message until
classResponsibility is called. This delays doesNotUnderstand errors
requiring the programmer to lookup up the debugger stack to find the
original culprit. But this should not be difficult for the programmer
to get used to.
Classes do not inherit from other classes. One would copy a class if he
wants to get similar behavior. But most behavior will be in Behavior
modules not classes, so you would only be copying accessors and
More information about the Squeak-dev