next up previous contents index
Next: 3.5 Control-flow Up: 3 The Slate World Previous: 3.3 Introspection   Contents   Index

Subsections

3.4 Traits

Slate objects, from the root objects down, all respond to the message traits, which is conceptually shared behavior but is not as binding as a class is. It returns an object which is, by convention, the location to place shared behavior. Most Slate method definitions are defined upon some object's traits object. This is significant because cloning an object with a traits delegation slot will result in a new object with the same object delegated-to, so all methods defined on that traits object apply to the new clone. There is one core method which drives derivation:

myObject derive &mixins: &rejects:
will return a new clone of the Derivable object with a traits object which is cloned from the original's traits object, and an immutable delegation slot set between the traits objects. If mixins are given, it will include more immutable delegation links between the new traits and the traits of the array's objects, in the given order, which achieves a structured, shared behavior of static multiple delegation. Note that the delegation link addition order makes the right-most delegation target override the former ones in that order. One interesting property of this method is that the elements of the mixins do not have to be Derivable.
In practice, the following wrapper is the appropriate method to use in common situations, since it handles the installation of the prototype in a cleaner manner:

obj addPrototype: name derivedFrom: parentsArray
will perform the effects of derive using all the elements of the Sequence in the same order as derive. It also assigns the name to the traits object's name attribute (which should be a Symbol) as well as using the name for the attribute between the surrounding object and the new prototype. Finally, it will compare the delegation pattern of the new object with the old, and only replace the old if they differ. In either case, the installed object is what is returned, and the existing traits object will be re-used if there is one.
obj define: name &parents: parentsArray &slots: slotSpecs
performs the effects of derive using all the elements of the Sequence in the same order as derive. The default parent is just Cloneable. It also assigns the name to the traits object's name attribute (which should be a Symbol) as well as using the name for the attribute between the surrounding object and the new prototype. The slotSpecs needs to be an array with either Symbols or Associations from Symbols to values, to specify (mutable) state-slots and their attributes. Finally, it will compare the delegation pattern of the new object with the old, and only replace the old if they differ. In either case, the installed object is what is returned, and the existing traits object will be re-used if there is one. A define:&builder: form is also provided which takes a block and uses its resulting value for the object; &builder: can be used in conjuction with &slots:, but not with &parents:, as no derivation is relevant.
As with any method in Slate, these may be overridden to provide additional automation and safety in line with their semantics.

3.4.0.1 Traits Windows

Beneath this simple system is a level of indirection which allows for greater control when necessary over the combination of parent behaviors; for most purposes, they may be ignored. What is actually the case is that each object points to an object in a traitsWindow delegation slot. The object held there delegates directly to all parents above it; the various parents will be labeled traits1.. traitsN, and a separate slot is created for the particular prototype's shared method, called traits, and this is where most method definitions are concerned.

This allows for a control over the order of precedence (via addDelegate:before:valued: and addDelegate:after:valued:) for any prototype deep into the normal derivation chains. This means that nearly all of the problems of precedence in a multiple inheritance graph may be resolved flexibly.6 There is also a hint to the lookup procedure in the traitsWindow objects that a meta-level has been reached. Once one meta-transition has occurred during lookup, the algorithm will not traverse such a transition again; thus Slate avoids a lookup confusion between methods meant for regular objects and those meant for the traits themselves.


next up previous contents index
Next: 3.5 Control-flow Up: 3 The Slate World Previous: 3.3 Introspection   Contents   Index
Brian Rice 2005-11-21