[GOODIE] Squeak Smalltalk: A Quick Reference (v. 0.0)

Ian Piumarta Ian.Piumarta at inria.fr
Sun Dec 5 12:54:54 UTC 1999


Andrew,

I just glanced through the SQR -- and I agree 100% that documents like
this, which "cut through the noise" to get directly at the important
stuff, are _immensely_ valuable.  I've not looked at anything in
depth, but one thing caught my attention:

    Class ProtoObject
    
    Squeak additionally supports an improper class ProtoObject, from which
    object hierarchies other than proper instances and proper classes can
    be derived.  ProtoObject, the improper subclass of class object has no
    instances.  Indeed, attempting to instantiate ProtoObject will likely
    result in a crash.

My understanding might be wrong, but I think the situation is slightly
different...

ProtoObject is the real root of the class hierarcy, and Object is
actually a subclass of ProtoObject.  ProtoObject represents the
"behaviourless object" -- the absolute minimum that is required to
exist "harmoniously" as an object in the image.  Object adds the
behaviour to ProtoObject that is required for objects to interact
"correctly" with the rest of the class hiercarchy (#copy, #isKindOf:,
#at:[put:], and so on).  The interest of ProtoObject is mainly for
building "proxies": objects that react to _arbitrary_ messages by
performing some fixed response, based on the messages that they
receive.

Proxies typically implement only "doesNotUnderstand: aMessage" (plus
maybe a few _very_ private helper methods), and then dissect aMessage
to figure out how to react to the situation.

Since their "reactions" to arbitrary messages should also be valid for
the normal "Object" messages (#copy, #isKindOf:, #at:[put:], and so
on) it's important that they *don't* inherit these from their
superclass.  Traditionally, the way to implement them was to create a
new _disjoint_ hierarchy: the "proxy" class was a subclass of nil,
just like Object.

Adding ProtoObject to the hierarchy makes things more consistent,
because being a subclass of ProtoObject is practically the same as
being a suclass of nil, but without introducing disjoint hierarchies
(which have some nasty effects on browsing implementors, and other
activities that try to iterate over the classes based on the hierarchy
using #allBehaviorsDo:).  ProtoObject also implements the behaviour
that allows iteration over all the instances in the image to function
correctly, and just enough protocol to allow ProtoObjects to be
distinguished from "nil" (identity, #isNil, #ifNil:, ...) to avoid
"inadvertently" triggering their #doesNotUnderstand:-based "reaction".

A good example of a "proxy" that inherits from ProtoObject is
ObjectOut, wich "reacts" to an arbitrary message by trying to "swap
in" an object stored on disk.  Now that Object is a subclass of
ProtoObject, one might consider one of Object's responsibilities as
being a proxy for "unimplemented behaviour" -- it "reacts" to
abritrary unknown messages by raising a MessageNotUnderstood Error.

Instantiating a ProtoObject currently does crash the system (that's a
little strong: let's say that rather that it causes the system to
abort deliberately) because of a recursive "message not understood"
error.  I personally consider this to be a (serious) bug.  Since *all*
the subclasses of ProtoObject implement #doesNotUnderstand:,
ProtoObject should also implement it to raise either a
MessageNotUnderstood Error, or (much) better still a
SubclassResponsibility Error.  At the very least, something like:

    ProtoObject>>doesNotUnderstand: aMessage
        Error new signal: 'this object cannot respond to this message'

I hope some of that makes sense, and is useful.

Regards,

Ian





More information about the Squeak-dev mailing list