creating new objects
Declaring a New Class
module NewObject() option object; ... end module;
Object( obj )
Object( obj, ... )
an existing object
To create a new class of objects, use the module declaration syntax and add option object. As with modules, names are declared in local and export statements. An object's local names can only be accessed from the methods in the class declaration, whereas export names can be accessed from anywhere.
In objects names can also have a second modifier, static. The static modifier affects how the value assigned to a name is shared among multiple objects of the same class. A name without the static modifier has a value that is tied to the object. Thus each object stores its own value for the name. A name with the static modifier has a value that is tied to the class, thus each object of the same class shares the same value for that name.
static is typically used for an object's methods, as the methods are the same for each object. The object's data members, those names which maintain the state in the object, generally do not have the static modifier. However there are cases where it makes sense to have a static data member (perhaps a class-wide counter to keep track of the number of objects created).
The result of executing a module declaration with option object is a new object of the declared class. This object is often treated as a special prototype object that is primarily used to create new objects of the same class. The module syntax allows for a name to be specified. This name will have the prototype object assigned to it and it will be protected.
Creating More Objects
Once a prototype object exists it can be used to create new objects using the Object routine. By default the new object's names are assigned the same values as the prototype's names. Objects can define a ModuleCopy method to change how the new object is initialized when the Object function is called. The Object routine can accept additional arguments which will be passed into the ModuleCopy method.
One nice way of handling new object creation is to use the ModuleApply method. By having ModuleApply call Object, you can create new objects by applying the prototype object's name.
If a class is declared by a module definition having option object(T0), then the new (so-called derived) class inherits all of the members of the class of the pre-existing object T0 (the base class).
Like all newly created objects, any inherited non-static members will be unique to the object instance created by executing the module definition.
Static members will be shared with the base class, or not, depending on the value they have in the base class. Static members whose value is a procedure or module with a ModuleApply function (methods) will be reinstantiated in the derived class. All other static members (i.e. data members) will be shared with the base class.
The module definition for a derived class is executed like any other, and may assign values to both newly declared and inherited members.
A derived class must not redeclare (via a local or export declaration) any members inherited from the base class. It can however change the value bound to such a member simply by assigning to it.
After the module definition is executed, any members that were not assigned values will inherit their values from the base class and object (T0). For inherited methods, any lexically scoped references to other members will be adjusted to refer to the derived class or object's members. Lexical references to members shared with the base class will also continue to work. Explicitly scoped references, such as T0:-someVar, will not be adjusted.
A method in a derived class that replaces an inherited method can invoke the base class' method by calling it explicitly. For example, a method M inherited by class T from class T0 but then reassigned in T, can call the original method using T0:-M().
Likewise, a method in a derived class can refer to (and assign to) a base class data member by referring to it explicitly, e.g. T0:-x := T0:-x + 1.
The following example illustrates the ideas presented on this page.
local value := 0;
local total::static := 0;
export amount::static := proc( self::Dollar, $ )
export in_circulation::static := proc( self::Dollar, $ )
export ModuleApply::static := proc( )
Object( Dollar, _passed );
export ModuleCopy::static := proc( new::Dollar, proto::Dollar, v::numeric, $ )
new:-value := v;
total := total + new:-value;
This creates a prototype object and assigns it to the name Dollar.
The Object routine can be used to make new instances of Dollar.
d1 ≔ Object⁡Dollar,1
Creating a new Dollar object also increases the value of the static variable total.
As Dollar implements a ModuleApply method to create new instances, the following syntax can also be used.
d5 ≔ Dollar⁡5
The value local is not accessible from outside Dollar's methods.
Error, module `Dollar` does not export `value`
Using the amount method, the value of a Dollar object can be returned.
The static local total is shared between all instances of Dollar, so you can pass any Dollar into in_circulation, and get the same result.
Download Help Document