Subclassing OrderedSequence

Andres Valloud sqrmax at prodigy.net
Thu May 3 15:54:30 UTC 2001


Hello.

>From your first message I got the impression you were implementing a
collection that behaved like anOrderedCollection but that the element
storage was different.

> > SomeCollectionClass class>>new should return an initialized and
> > ready to use collection.
> which completely misses the point.
> 
> For argument's sake, suppose you have
> 
>     OrderedCollection subclass: #CardHand
>         instanceVariables: 'player'

Although CardHand can be thought of as a particular collection plus
other stuff, I feel it behaves in an essentially different way. CardHand
is used to play.

> and you define
> 
>     "CardHand>>"copyEmpty
>         ^(self class new: 0) player: self player; yourself

This suggests that CardHand should be a subclass of Object or another
suitable object, and that it should support card handling by delegating
rather than by subclassing.

The assumption here seems to be "a card hand is an ordered collection
plus other stuff". The moment you run into statements like that, you
usually lose. In the future, you may want the cards to be sorted
according to a sortBlock. In this case, delegating the card storage
instead of gaining it by subclassing would make the problem a
no-brainer, consisting of just replacing the sole reference to
OrderedCollection in CardHand (in CardHand>>initialize, to be more
precise) with a reference to SortedCollection.

Earthquakes will smash buildings that are not flexible enough. Change
does the same to software.

> Now
>     hand select: aBlock
> will always return a CardHand with the right player, whether the result
> is empty or not.

This should be in an SUnit test, any implementation that passes the
tests is correct. The simplest thing that could possibly work would be,
IMHO, to delegate card storage instead of trying to fix collateral
effects in a subclass of OrderedCollection... in that way, you also
avoid tying your implementation to a particular collection class.

> [then, the definition of many methods to patch collateral damage follow]

This is collateral damage you can avoid by subclassing Object.

>         > Before doing this, is there any agreed way to decide which selection/
>         > filtering/slicing methods should return OrderdCollections and which
>         > should return objects of the new subclass?
> 
>         The ANSI Smalltalk spec fits your request very well. The idea,
>         basically, is that for instance #collect: sent to aSortedCollection may
>         produce elements that are not comparable with the sorted collection's
>         sortblock. Therefore you return anOrderedCollection.
> 
> That really doesn't help.  The case where the result *can't* belong to the
> new type because it doesn't satisfy the class invariant is obvious.

I said that the idea was *basically* and *for instance*. What you asked
for is in the ANSI spec. Did you actually check the ANSI spec at all? It
specifies the behavior of all the methods you mention...

> I can live with my present situation, where #copy returns an object of the
> new class but #copyFrom:to: does not.

Try subclassing Object. You get the same behavior and possibly a simpler
implementation for much less effort.

Andres.





More information about the Squeak-dev mailing list