development styles

Jecel Assumpcao Jr jecel at merlintec.com
Wed Aug 23 15:45:16 UTC 2000


On Mon, 21 Aug 2000, David Ungar wrote:
> You really have the Self-style down pat!

Thanks! I gradually developed this style during the 1980s and that is
what attracted me to Self when I found out about it. There were two
lessons I have learned with Self 4:

1) Create parent just before first cloning an object.

If you make a few clones of an object and then decide to change
something, it will be rather complicated. In the old Self 1.0 days this
wasn't really a problem since we would edit the text file and create
fresh clones after reading in the changed prototype.

To avoid this problem, when I started using Self 4.0 (and so changing
running applications instead of always restarting) I would create an
empty parent object for every "normal" object. But this was going to
far in the opposite direction as several of these objects ended up
never being used. So now I don't create these parents until it is
obvious that I will be using them soon.

This doesn't solve all my problems, however, since I can't add state to
a prototype and all existing clones. In the peg solitaire example I
could have added 'north', 'west', 'south' and 'east' slots to each
holeMorph in order to give the board a notion of topology. But this
would be hard to do since I already had 33 separate holeMorph objects.
It was easier to create an external allMoves data structure to handle
this. I hope my "slices" user interface idea can be used to allow you
to make changes to a set of objects all at once and so let you evolve a
program even if you forgot to include a shared parent in the object
structure.

2) Change the morphTypeName before changing anything else.

Not doing so makes it too tempting to have implied morph structure
creep into the code. My geneMorph is a prime example of this - the code
in the 'score' method only works as long as there is only one
labelMorph (the one representing the score). How likely is it that this
will change in the future breaking the code? It would be equally easy
to assume that only holeMorphs are ever embedded in the board object.
Or that any circleMorphs that are embedded actually represent holes.
Either option will cause problems soon enough - it is much better to
change the morphTypeName for these circles to 'holeMorph' and to
explicitly test for this before sending a specific message like
'hasPeg:'.

Of course, this is a very bad and fragile use of reflection. If I make
a special kind of holeMorph then I will either have to give it a new
name ('cornerHoleMorph', for example) and the board will no longer see
it as a holeMorph or I will keep the same name but then have to add
other tests. A less reflective alternative would be to have my new
morph answer true to the message 'isHole' and all other morphs answer
false. That requires patching traits morph for each new kind of morph
that I create, which isn't such a good idea. A better reflective
alternative would be to have some way of asking if an object implements
a given protocol - all we are really interested in is whether the
object will understand a message we are about to send it or not.
Something like:

        (holeProtocol isImplementedBy: m) ifTrue: [ m hasPeg: true ].

I am learning....

-- Jecel



More information about the Self-interest mailing list