[squeak-dev] Re: Object>>#is:? (was: Re: PackageDependencyTest)

Andreas Raab andreas.raab at gmx.de
Thu Mar 4 21:56:32 UTC 2010


On 3/4/2010 11:44 AM, Stéphane Rollandin wrote:
> I don't see how #is: can work in the large.
>
> suppose I need test selectors like isMorph, isBorderedMorph, isMyMorph
> and isMySpecializedMorph

Here is what you'd do:

.
.
.
.
.
.

Nothing. All that you're describing is already there. To wit:

	Morph new is: #Morph => true.
	BorderedMorph new is: #Morph => true.
	BorderedMorph new is: #BorderedMorph => true.
	Array new is: #Morph => false

Works out of the box. You can then start to have fun, say:

SystemDictionary>>is: aSymbol
   ^aSymbol == #Squeak or:[super is: aSymbol]

and now:

	Smalltalk is: #Dictionary => true
	Smalltalk is: #Squeak => true
	Smalltalk is: #Cuis => false

> every Morph must have
>
> is: aSymbol
> aSymbol == #Morph ifTrue: [^ true].
> ^ false

No. See above.

> then BorderedMorph must implement
>
> is: aSymbol
> (super is: aSymbol
> or: [aSymbol == #BorderedMorph]) ifTrue: [^ true].
> ^ false

No. See above.

> now MyMorph (supposedly a BorderedMorph) has
>
> is: aSymbol
> (super is: aSymbol
> or: [aSymbol == #MyMorph]) ifTrue: [^ true].
> ^ false

No. See above.

> so far so good, although at the moment all this code would be replaced with
>
> isMorph
> ^ false
>
> isBorderedMorph
> ^ false
>
> isMyMorph
> ^ false
>
> in Object, and the corresponding
>
>
> isMorph
> ^ true
>
> isBorderedMorph
> ^ true
>
> isMyMorph
> ^ true
>
> at the proper places

Which is the point here. These six methods are being removed without 
replacement. You get all of this for free.

> let's now consider MySpecializedMorph, a subclass of MyMorph that I *do
> not* want to be considered as MyMorph:
>
> is: aSymbol
> (super is: aSymbol and: [aSymbol =~ #MyMorph])
> or: [aSymbol == #MySpecializedMorph]) ifTrue: [^ true].
> ^ false
>
> see the problem ?

This is the first situation where you'd actually have to implement is:

MySpecializedMorph>>is: aSymbol
   ^aSymbol ~~ #MySpecializedMorph and:[super is: aSymbol]

I fail to see any problem whatsoever.

> I have to be aware of the behavior of each implementation of #is: in the
> upward inheritance chain if I want to produce the proper tests. Going
> down, those tests will become more and more complex and hard to grok.

This is a valid concern but rather unlikely from my point of view. You 
don't have to use #is: if you don't want to. It's entirely optional. You 
can still go ahead and monkey-patch those isMethods where you'd like to 
- in some cases this will be advantageous for clarity, in others for 
performance, and where that's true, we should absolutely use them. The 
use of #is: isn't a dogma, it's a tool that will be helpful for 
situations that we currently don't have a good approach for.

> Plus, reimplementing any of the #is: can possibly break any of the #is:
> in subclasses. So all #is: implementations in a given hierarchy are
> actually dependent. It's pure spaghetti code, as far away from OOP as it
> gets.
>
> I guess I'm missing something. how is this supposed to work ?

See above. It's straightforward. Some of your concerns are valid, but 
the current situation is highly undesirable: Hard code class references, 
and gazillions of isFooBar methods don't make the system any more OOP 
either.

We need to find a middle ground here and the #is: protocol helps with that.

Cheers,
   - Andreas



More information about the Squeak-dev mailing list