Object: Identity vs. Environment

Joel Shellman joel at ikestrel.com
Fri May 30 05:33:14 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.

Right, this is #2 I had listed previously. At this point, that seems to be
making the most sense to me.

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

Please give an example. If they have to make distinctions, than that means
they're not able to accept *anything*.

> 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.

"whether Attribute will accept them": how is that defined? Attribute should
be able to accept anything that it can properly interact with, right? Which
is another way of saying that it responds to a certain protocol. It will
understand certain messages I plan to send to it when I have to interact
with it. That's a protocol/interface/set of methods/whatever you want to
call it.

> 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.

Right--highly undesirable..

-joel



More information about the Squeak-dev mailing list