Solving the problem of isSomeClass

Joel Shellman joel at ikestrel.com
Sun Jun 15 07:27:51 UTC 2003


> Hola again-
>
> A few days ago
>
> Looking at Morph, I see there are 18 methods in the classification
> category, all isSomething methods.
>
> Perhaps in DNU: we could implement a check- if the method being called
> isn't understood, and 1. begins with "is" and then 2. is followed by
> the name of a class (capitalized), return the result of isKindOf:
> thatClass.

I apologize if I don't understand the context of your port. I thought I
would put this forth, though, if it might be useful:

To paraphrase what someone else said recently, it might be better to not put
in hacks because we're not willing to take the time to clean things up.

I may be using the wrong image or maybe there is non-static references that
the "senders of" function doesn't find, but here are some random ideas after
a quick perusal of a few things:

1) isAlignmentMorph is used only once
2) isBalloonHelp is never used
3) isModalShell is never used
4) isPrefab

PrefabManager>>privateRemoveMorph: aMorph
 "If aMorph is a prefab, notify the resizer of the change."

 (aMorph isPrefab and: [resizer notNil and: [resizer hasClient: aMorph]])
  ifTrue: [resizer removeClient: aMorph].

 super privateRemoveMorph: aMorph.


Couldn't this be:

  resizer removeClient: aMorph.
  super privateRemoveMorph: aMorph

If you don't like the Null Object pattern (apparently not being used in this
class, but it would need to be for the above), you could wrap the resizer
call in a notNil conditional. The conditional about whether the resizer
should worry about it or not should be inside the resizer's method,
shouldn't it? And if the resizer only has prefab's in it's list, then the
isPrefab and hasClient are redundant.

In fact, one could probably use an Observer Pattern with the resizer
registering to observe the morph being deleted and completely remove this
method and rely on the super implementation of it.

5) isRenderer

Player>>getLength
 "Answer the length of the object"

 | aLength cost |
 ((cost  _ self costume) isKindOf: PolygonMorph) "annoying special case"
  ifTrue:
   [^ cost unrotatedLength].
 aLength _ cost renderedMorph height.  "facing upward when unrotated"
 cost isRenderer
  ifTrue:
   [aLength _ aLength * cost scaleFactor].
 ^ aLength

Apparently everything determining the length is in the costume instance
variable, so shouldn't this method just delegate to:

^costume getLength

And the costume would be polymorphic to return properly if it was a
PolygonMorph, or if it had #isRendererness and so no #is* would be needed at
all.


Are suggestions like this useful and on the right track?

-joel



More information about the Squeak-dev mailing list