[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: inheriting data slots
> 3) use _AddSlots: and _RemoveSlots: like this (this is using the old
> prototypes _DefineSlots: (|
> TDpoint = (|
> parent* = traits TDpoint.
> "inheriting is a global variable"
> inheriting: prototypes point copy
> inheriting _RemoveSlots: 'parent'
> prototypes TDpoint _AddSlots: inheriting
You can achieve this without the "evil global" in this way (using the new
programming primitives--note that _Define: makes the receiver 'look just
like' the argument object by removing all slots in receiver and adding
slots found in the argument to the receiver):
prototypes _AddSlotsIfAbsent: ( | TDpoint = () | )
TDpoint _Define: point "now TDpoint looks just like a (2d) point"
TDpoint _AddSlots: ( |
parent* = traits TDpoint. "overwrites the parent slot"
z <- 0. "adds new data slot"
This, like method #3 above, relies on the convention that the parent slot
is named "parent". (This is the one piece of information that TDpoint needs
to know about the prototype point.)
New programming primitive note:
It may be tempting to fold the first two lines into one, thus:
prototypes _AddSlotsIfAbsent: ( | TDpoint = point copy | )
But this should not be done: if the prototype point object is changed (say
you add a slot for its color) and you re-read in the script file that defines
this TDpoint, _AddSlotsIfAbsent: will see a slot called "TDpoint" already
in prototypes, and have no effect. Then the TDpoint prototype won't have
a chance to get a copy of the new color slot.
In general, the slots in _AddSlotsIfAbsent: should always be initialized
to () (an empty object), and all useful programming should be done outside
of it, via _Define: and _AddSlots:. This is to avoid situations like the
one above. (The one exception is for objects that want to have a byteVector
or objVector part--these need to be initialized to a copy of [byte]vector
in _AddSlotsIfAbsent:, since _Define: only affects slots.)