Object: Identity vs. Environment

Richard A. O'Keefe ok at cs.otago.ac.nz
Fri May 30 01:07:54 UTC 2003


Surely the rule for isFoo methods is simple?

There is a method which at some point may have to deal with
objects of several different classes (some of which may not
be known to the designer at the time of writing).

For example, in my XML code, practically everything I do has
to cope with
 - a Symbol (representing an entity reference)
 - a String (representing parsed character data)
 - a processing instruction node
 - an element node
(let's not even think about comments or CDATA sections, neither of
which should be exposed to structure-based applications).
Of these node types, only two are allowed in attribute values.
Suppose I want to gather "text" from an element in order to
stuff it in an attribute value.  I want to write something like

    attVal := OrderedCollection new.
    thisNode doAll: [:each |
        each isTextual ifTrue: [attVal add: each]].

The method #isTextual goes in Symbol, String, PI, and Element.
If someone wants to add new node types (such as CDATA, perish
the thought), it's their job to add isTextual there too.

In this case, it is important NOT to put #isTextual in Object,
because if someone adds a new node type, we don't want some
default value returned, we want a DNU so that whoever added the
new node type is reminded to implement the full protocol that
XMl nodes are supposed to have in common.

So you ensure that your #isFoo method is defined in all and only
the classes you expect to be given.

But *some* methods really can be given *anything*,
and for those methods it is perfectly legitimate to put the
discriminations they need in Object.

Note that "is a descendant of some class" is the WRONG notion here;
if I made entity references some other class that _had_ a Symbol
instead of _being_ a Symbol, there would be no inheritance relation
between String and EntityRef.

Note that "responds to a protocol" is the WRONG notion here;
the important question is not whether #PCDATA and &entity respond
to some protocol that other things don't, but whether Attribute
will accept them.

An alternative would be
    Attribute class>>
    accepts: aNode
        ^aNode class == String class or: [aNode class == Symbol class]
but this is precisely the kind of case-statement-on-class which we
_don't_ want to have in our code for the old familiar reasons.



More information about the Squeak-dev mailing list