Skip to content
Baltasar García Perez-Schofield edited this page Jan 15, 2018 · 1 revision

Trait objects

While the way to create objects shown in the basic usage section is simple enough, the resulting schema is not the most efficient one. Specifically, each time a new Point instance is created, all its members are copied, including methods. However, methods are not likely to change often, and aynway, in the event of a change needed for a specific instance, that method can be overwritten. Also, we lose the possibility of making a change in a method that affects all instances, present in class-based programming languages.

In order to solve all of this, prototypes can be separated in state and behaviour, being the latter the so-called trait objects.

The creation of the object holding the state follows.

> (anObject copy) rename "Point"
Point
> Point.x = 0
Point
> Point.y = 0
Point

Now, we create the object holding all methods, the behaviour or traits object.

> (anObject copy) rename "TraitsPoint"
> TraitsPoint.moveTo = { a b: self.x = a; self.y = b }
> TraitsPoint.str = {: ( ( ( self.x str ) + ", " ) + ( self.y str ) ); }

The problem is: how do we relate both objects? At this point, we have to talk about inheritance. Inheritance is implemented via the parent attribute, always present in any object but not specifically mentioned. If we list both objects:

> TraitsPoint list
Point: Object = {
    str  = {: ( ( ( self.x str ) + ", " ) + ( self.y str ) ); }
    moveTo a b = {a b : ( self set "x" a ); ( self set "y" b ); }
}

> Point list
Point: Object = {
    x: Int = 0
    y: Int = 10
}

Note that objects are listed as, for instance, Point: Object = {.... That Object after the colon is the object pointed by the parent attribute, as shown below.

> Point.parent
Object = { }
> TraitsPoint.parent
Object = { }

Object does not hold any attribute, its main role is to keep the shared behaviour for all objects. For example, the copy method is stored in Object. Inheritance is implemented by delegation. When a method for responding a message cannot be found in the object, the satisfaction is delegated in the object pointed by parent. This means that, when the message Point copy is sent, the copy method is not found inside Point, so the parent attribute is followed to Object, where the method is located.

Following this schema, the parent attribute of Point can be changed to TraitsPoint, meaning that moveTo and str are available from the former. When copying a new instance, the parent attribute is also copied, so the new instance will have its parent pointing to TraitsPoint. That way, the behaviour (the set of methods) is not copied in instance creation, and is shared by all instance. The possibility of and individual object sporting an particular implementation for any method can still be achieved by overwriting the method for that object.

> Point.parent = TraitsPoint
Point
> (Point copy) rename "p0"
p0
> p0 moveTo 10 10
p0
> p0
10, 10
Clone this wiki locally