Next: 3.5 Control-flow
Up: 3 The Slate World
Previous: 3.3 Introspection
Contents
Index
Subsections
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.
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: 3.5 Control-flow
Up: 3 The Slate World
Previous: 3.3 Introspection
Contents
Index
Brian Rice
2005-11-21