Frag Logo
  Frag Home | Frag SF Project   index | contents | previous | next

Frag Object System

This section gives an overview of the Frag object system. For details of the predefined methods for all objects, please refer to reference of Object presented below (in Section Object: Method Reference).

Objects and Classes

Object and Class Concept

Frag is an object-oriented language, but in contrast to many other object-oriented languages, in Frag every entity is represented by an object. An object can play the role of a class or a superclass as well, when this is required. The class concept of the language is not fixed but can be tailored to the current situation.

In Frag all relationships of an object, including class and superclass relationships, might possibly be changed at any time. When an invocation takes place, the invocation is dispatched within the current context of the object. The standard dispatch algorithm of Frag first looks up the classes and superclasses of the object, calculates the dispatch order, and then dispatches the invocation in this context.

Note that this dynamic lookup does not mean a problematic performance penalty in most cases because Frag optimizes the dispatch performance by caching the lookup order. More important, Frag is not intended to host the performance-intensive parts of the application - this is the role of the (e.g. compiled) host language (in case of Frag this is typically Java). Frag is used solely for composition and configuration, and other high-level tasks, such as building DSLs.

Defining Objects

Each object can have one or more classes, but each object in Frag has at least one class. An object always has at least the class Object, the most generic class in the Frag object system. Each other class is a subclass of Object. This way it is ensured that every object in Frag can use the features defined by the class Object.

An object is created by invoking the method create of its class. For instance, we can create an object Connection1 from the most general class Object:
Object create Connection1
This invocation means that a new object with the object ID Connection1 is created. This new object has the class Object.

Alternatively, we can create objects which are unnamed by omitting the object ID in the create invocation:
set connection1 [Object create]
An unnamed object is immediately garbage collected, once there are no more references to it. That's the reason, why we stored the object ID in the variable connection1, directly after it was created. If we don't do this, the object is lost. For instance, the object created in the following invocation is directly removed from the interpreter by the garbage collector:
Object create
Unnamed objects have an automatically assigned ID, of the form: %%number, such as %%12. Named objects have an initial reference, their name. Only if this name is forgotten, e.g., using the method unname, they can automatically be garbage collected.

It is advisable to use named objects for instances that should survive, even if no one references them. Typical examples are objects that are used as classes: They are typically realized as named objects. Unnamed objects are used for short-living instances, or for instances that occur in great numbers or consume a lot of memory, and hence they should get garbage collected, once they are not in use anymore.

The Classes Relationship

We have already seen that the method create can be used to derive an object from a class. Consider we want to create a class SocketConnection, and derive an object Connection2 from this class:
Object create SocketConnection
SocketConnection create Connection2

In the context of Connection2, the object SocketConnection acts as a class. Note that there is no difference in how we have created SocketConnection and Connection1; at this point both are ordinary objects. The subsequent creation of Connection2 is what makes SocketConnection (also) a class. SocketConnection acts as a class only in the context of Connection2.

In this example it makes not much sense to derive objects from Connection2; thus it will likely not act as a class. But note that this two-level class concept is not always applying. For instance, we might want to constrain or extend the features of SocketConnection. Consider Frag does not implement the SocketConnection itself, but it is a wrapper for a Java class. That means somewhere we need to define how to access the Java counterpart of SocketConnection, and this implementation should be reusable for all Java classes. This can be done by giving the SocketConnection itself a class JavaClass which can be used for providing wrappers to other Java classes as well:
Object create JavaClass 
JavaClass create SocketConnection 
SocketConnection create Connection3

This feature is actually quite important when using Frag for model-driven software development, and other use cases where models, meta-models, meta-meta-models, etc. must be represented in Frag: For all meta-levels the same base language syntax, as well as all the predefined features of Frag like inheritance, can be used and the number of meta-levels is not restricted in any sense.

In Frag, each object can have multiple classes. Consider a simple example: we want to log the invocations of Connection3 using the class ConnectionLogger. This class can be added to Connection3 by adding it to the existing class SocketConnection using the method classes. classes can be used to dynamically change the classes of an object at any time:
Connection3 classes ConnectionLogger SocketConnection

Now Connection3 has two classes, ConnectionLogger and SocketConnection. Later on you can drop the ConnectionLogger class again:
Connection3 classes SocketConnection

The Superclasses Relationship

In Frag each class can also have one or more superclasses. Superclasses are defined for a class using the method superclasses. The superclass relationship is also dynamic, and can be changed at any time. Per default, each class has the superclass Object. This class does not have to be explicitly provided as a superclass, but it is automatically assigned. For instance, if we want to provide a class for logged connections, we can provide the two classes ConnectionLogger and SocketConnection as superclasses:
Object create LoggedSocketConnection -superclasses ConnectionLogger SocketConnection

Multiple superclasses can be used to implement the concept of multiple inheritance in a dynamic fashion.

Making an Object its own Class

Each Frag object can have any other object as its class by providing it in its classes relationship. Among these classes the object itself can be listed. That simply means that the object (and its superclasses) are also searched during the search for methods. This is for instance useful when only one instance of the class is existing (a "Singleton") or when we need to have access to the class before an instance is created (this is similar to accessing a static method in Java). A prominent example of such a class is Object that has only the class Object. Object itself defines the method create, for instance. Create would not be resolved on Object, if Object would not be on its own class hierarchy.

As another example, consider a Factory object. We want to be able to derive objects with a method new directly from it, but we do not want to instantiate the Factory, as it is needed only once in the system. Hence, we add it to its own class list:
Object create ConnectionFactory
ConnectionFactory method new {name} {...}
ConnectionFactory classes ConnectionFactory
...
# "new" is resolved via the self object used as a class
ConnectionFactory new a
ConnectionFactory new b

Introspection Options

Because Frag is designed for runtime composition, an important goal is to be able to find out about the current composition and state of the objects at any time. Therefore Frag is designed as a fully reflective language, offering introspection options for each language element and feature it introduces.

Introspection of objects is realized via ordinary, predefined instance methods, especially of Object (introspection of features of an object) and interp (introspection of features defined for the whole interpreter, such as all objects). Introspection options have - as a convention - a name starting with "get" like "getClasses" or are worded as a question like "isType".

Examples for introspection options follow in the next section.

For all predefined introspection options, see Sections Object: Method Reference and Accessing the Interpreter.

Reflection on Class and Superclass Relationships

There are rich introspection options, defined for the object and class relationships, introduced before (see the instance methods of Object defined in Section Object: Method Reference).

For example, we can ask an object for its current classes using getClasses. In the example above:
Connection3 getClasses
would return:
ConnectionLogger SocketConnection

A sometimes handy short-cut is getClass, which returns the first class in an object's class list. Typically the first class is the one that is used during create to derive the object.

Consider you want to add a ConnectionLogger to an object using classes. Hard-coding class names might overwrite other extensions and thus this is not a good solution. With the introspection option classes, we can add the ConnectionLogger by appending it and the current classes (without knowledge of their current value):
Connection3 classes ConnectionLogger [* Connection3 getClasses]

Please note that the "[* ...]" substitution uses the expand syntax explained in Section Expand Syntax.

In the same way as above, we can ask a class for its superclasses using getSuperclasses. In the example above:
LoggedSocketConnection getSuperclasses
would return:
ConnectionLogger SocketConnection

Mixins

In Frag, in addition to the classes and superclasses relationships, there is an additional relationship of objects that provides a type for an object: mixins. Each class can have one or more mixins. Mixins are defined for a class using the method mixins. The mixin relationship is dynamic and can be changed at any time. Per default, a class has no mixins. For instance, if we want to log a connection class, we can provide a class ConnectionLogger as a mixin:
Object create SocketConnection \
    -superclasses Connection -mixins ConnectionLogger

The mixin relationship is almost identical to the superclasses relationship, except that all mixins are invoked before the class itself and its superclasses are invoked. That is, when a method invocation is dispatched, ConnectionLogger is searched before SocketConnection and Connection. As a consequence, the mixin's methods overshadow all methods of the class and the superclasses. Hence, the mixin can be used to intercept method invocations of the class that it is mixed on. This is especially useful in combination with the command next (see Section The "next" Command), which allows you to implement around, before, and after interception of messages, as it can for instance also be found in AOP languages and frameworks.

For more on the dynamic mixin concept in general see the Document Object-based and class-based composition of transitive mixins. More details of mixins in Frag are provided in Section Class Hierarchy and Class Path Linearizing.

Object: Method Reference

Object

append

Syntax

<objID> append <variableName> ?new elements ...?

Description

append appends an arbitrary number of new elements to a given list stored in the object's variable variableName.

Example

The following code returns the list a b c 0 2:
Object create o
            o set a {a b c}
o append a 0 2
o get a

classes

Syntax

<objID> classes <class1> ?... classN?

Description

classes defines a number of classes for objID. Existing classes are overwritten. Hence classes dynamically changes the classes of a class. <class1> ?... classN? must be existing classes; if one of those classes does not exist, an error is raised.

An object must have at least one class. The class an object is created from is given to it upon creation. That is, each object has after creation exactly one class. You can use classes to add more classes or change the classes.

Example

In the following code, Q is created from Object and directly afterwards, two classes are assigned to Q. Then the class list is printed. Afterwards, the classes are removed, by re-classing to Object.
Object create O
Object create P
Object create Q -classes O P
puts "classes of Q: [Q getClasses]"
Q classes Object
puts "classes of Q: [Q getClasses]"

configure

Syntax

<objectID> configure <configure args> ?more configure args ...?

Description

configure is internally used by create (see Section create) to invoke the configure arguments (see Section Configure Arguments). configure can be used to access this configuration mechanism on an existing object (without creating a new object).

Example

The following code performs a configuration, which calls set two times as a configure argument on an object. The values of the variables that have been set are then read using get:
Object create x
# do something else and then late configuration
# ...
x configure -set r 15 -set x 13
puts "var values: r=[x get r], x=[x get x]"

create

Syntax

<objID> create ?objectName? ?additional args ...?

Description

create creates a new instance of the class objID. If objectName is given a named object is created. If objectName is omitted, an unnamed object is created. For details about object creation see Section Object and Class Concept.

create can take an arbitrary number of additional args, which are treated as configure arguments, starting with -. See Section Configure Arguments for more details on configure arguments.

Example

The following code creates an instance x of the class Object, and invokes set two times as a configure argument. The values of the variables that have been set are then read using get:
Object create x -set r 15 -set x 13
puts "var values: r=[x get r], x=[x get x]"

defaults

Syntax

<objID> defaults <defaultList>

Description

defaults defines - on a class - default values for variables for the class' instances. The variable slots are created during object creation of the instance.

Example

If a class needs to predefine variables to be set for all of its instances, we can use the defaults method, as in the following example:
Object create D -defaults {
    aScalar 1
    aList {}
}

The above defaults statement specifies that whenever an instance of D is created, this instance gets a scalar variable aScalar with the default value 1, as well as an empty list variable aList.

deleteMethod

Syntax

<objID> deleteMethod <methodName>

Description

deleteMethod deletes a method dynamically from an object. methodName must be an existing method of the class objID.

Example

The following code creates a trace method for creation of objects on Object. As this method might be called rather often, it is advisable to remove it once the debugging output is not needed anymore.
Object method init args {
    puts "[callstack class] [callstack method]"
    next
}
# ...

# when not needed anymore: discard the method
Object deleteMethod init

get

Syntax

<objID> get <var>

Description

get reads an object variable var and returns its value. If the variable does not exist, get throws an error.

Example

The following code sets a variable on object o and then reads it using get:
Object create o
o set r 1
puts "value of r: [o get r]"

getArgs

Syntax

<objID> getArgs <methodName>

Description

getArgs returns the list of arguments of the method methodName.

Example

The following example returns the list of arguments of a method (i.e., the list a b c):
Object create O
O method m1 {a b c} {puts "$a $b $c"}
puts "args of m1: [O getArgs m1]"

getBody

Syntax

<objID> getBody <methodName>

Description

getBody returns the body (i.e., the code) of the method methodName.

Example

The following example returns the body of a method (i.e., the puts statement in the body of m1):
Object create O
O method m1 {a b c} {puts "$a $b $c"}
puts "body of m1: [O getBody m1]"

getClass

Syntax

<objID> getClass

Description

getClass is a short form of getClasses, returning just the first class of an object (typically the one used to create an object).

Example

The following code just prints X1, the first class in the class list of O.
Object create X1
Object create X2
Object create Y1
Object create O -classes X1 X2 Y1
puts "[O getClass]"

getClasses

Syntax

<objID> getClasses ?-options ...? ?pattern?
Options: -all or -direct

Description

getClasses returns the list of all classes defined for the object objID. It takes an optional pattern argument, which performs a pattern matching on the list of classes before returning it, as its last argument (for details on pattern matching see Section Pattern Matching). Per default, or when the option -direct is chosen, only the direct classes are returned. -all returns the list of all direct and indirect classes defined for the object objID (computed recursively).

Examples

The following code creates three objects and makes them classes of object O. Then O is queried for its classes, which returns: X1 X2 Y, and all classes starting with X, which returns X1 X2.
Object create X1
Object create X2
Object create Y
Object create O -classes X1 X2 Y
puts "[O getClasses], [O getClasses X*]"
The following code creates three objects and makes them classes of object O. One of those objects has a superclass S1. Then O is queried for all its direct and indirect classes, which returns: X1 S1 X2 Y1 Object, including all superclasses (S1 and Object). The query for all classes starting with X, returns X1 X2.
Object create S1
Object create X1 -superclasses S1
Object create X2
Object create Y1
Object create O -classes X1 X2 Y1
puts "[O getClasses -all], [O getClasses -all X*]"

getConfigureArg

Syntax

<objID> getConfigureArg <variableName> <configureArg> ?cutTheArg?

Description

getConfigureArg is a helper method that reads configure argument syntax elements from a variable variableName. Optionally, the configure argument can be cut from the variable variableName.

Example

In the following example, configure is overloaded and an additional configure argument -debug is introduced. A debugger is informed if a widget has this option. However, as there is no method debug on Widget defined, to avoid an error we must cut the configure arg from the args variable before passing its content on using next.
Object create debugger -set widgetList {}
Object create Widget
Widget method configure args {
    if {[catch {self getConfigureArg args "-debug" 1}] == ""} {
        debugger append widgetList [self]
    }
    next
}
Widget create w
w configure -set color blue -set backgroundColor black -debug 1
Widget create v
v configure -set color blue -set backgroundColor black

getDefaults

Syntax

<objID> getDefaults

Description

getDefaults returns the default values that a class defines for its instances, see Section defaults.

Example

The following code prints the list of defaults defined for D as a list. The result is a 1 {a b } 2 {a b c} {1 2 3}.
Object create D -defaults {
    a 1
    "a b " 2
    "a b c" {1 2 3}
}
puts "[D getDefaults]"

getInstances

Syntax

<objID> getInstances ?-options ...? ?pattern?
Options: -all or -direct

Description

getInstances returns the list of all instances defined for the object objID. It takes an optional pattern argument, which performs a pattern matching on the list of instances before returning it (for details on pattern matching see Section Pattern Matching). Per default, or when the option -direct is chosen, only the direct instances are returned. -all returns the list of all direct and indirect instances defined for the object objID (computed recursively).

Examples

The following example shows an object O which has three instances: two created by O and one acquired by re-classing. The list of instances is x1 x2 y1. All instances starting with x are x1 x2:
Object create O
O create x1
O create x2
Object create y1
y1 classes O
puts "[O getInstances], [O getInstances x*]"
The following code creates a number of instances from S1. All except for O are included in the allInstances list, because O is reclassed to Y1 and hence not an instance of S1 anymore. The two instances created from X1 are also included because X1 is subclass of S1 and hence c1 and c2 are indirect instances of S1. The result of all instances is X1 X2 Y1 c1 c2. X1 X2 is the sub-list that starts with X.
Object create S1
S1 create X1 -superclasses S1
S1 create X2
S1 create Y1
S1 create O -classes Y1
X1 create c1
X1 create c2
puts "[S1 getInstances -all], [S1 getInstances -all X*]"

getMethods

Syntax

<objID> getMethods ?pattern?

Description

getMethods prints the list of all methods defined for an object. It takes an optional pattern argument, which performs a pattern matching on the list of methods before returning it (for details on pattern matching see Section Pattern Matching).

Example

The following code defines an object with 3 methods. Next it prints the list of all methods and then all methods starting with x. The result is: {x2 x1 y1} {x2 x1}.
Object create O
O method x1 {} {;}
O method x2 {} {;}
O method y1 {} {;}
puts "[O getMethods] [O getMethods x*]"

getMethodType

Syntax

<objID> getMethodType <methodName>

Description

Each method has a method type, which indicates how the method is internally implemented (using which Java class). All user-defined methods have the type FragMethod. The Java-defined methods are of the type JavaMethod. getMethods allows you to query the method type information.

Example

The following code returns FragMethod JavaMethod because x1 is a user-defined method, and Object's set is implemented in Java.
Object create O
O method x1 {} {;}
puts [O getMethodType x1]
puts [Object getMethodType set]

getMixinOf

Syntax

<objID> getMixinOf ?-options ...? ?pattern?
Options: -all or -direct

Description

getMixinOf returns the list of all classes which have objID defined as a mixin. It takes an optional pattern argument, which performs a pattern matching on the list of subclasses before returning it (for details on pattern matching see Section Pattern Matching). Per default, or when the option -direct is chosen, only the classes who have objID as direct mixin are returned. -all returns the list of all direct and indirect classes who have objID as mixin (computed recursively).

Examples

The following code creates a mixin hierarchy and first prints all classes S1 is direct mixin of, which are X1 X2 Y1, and then the sub-list starting with X, which is X1 X2.
Object create S1
Object create X1 -mixins S1
Object create X2 -mixins S1
Object create Y1 -mixins S1
Object create O -mixins X1
puts "[S1 getMixinOf], [S1 getMixinOf X*]"
The following code creates a mixin hierarchy and first prints all classes S1 is direct or indirect mixin of, which are X1 O X2 Y1, and then the sub-list starting with X, which is X1 X2.
Object create S1
Object create X1 -mixins S1
Object create X2 -mixins S1
Object create Y1 -mixins S1
Object create O -mixins X1
puts "[S1 getMixinOf -all], [S1 getMixinOf -all X*]"

getMixins

Syntax

<objID> getMixins ?-options ...? ?pattern?
Options: -all or -direct

Description

getMixins returns the list of all mixins defined for the object objID. It takes an optional pattern argument, which performs a pattern matching on the list of superclasses before returning it (for details on pattern matching see Section Pattern Matching). Per default, or when the option -direct is chosen, only the direct mixins are returned. -all returns the list of all direct and indirect mixins defined for the object objID (computed recursively).

Examples

The following code creates a mixins hierarchy and first prints all the direct mixins of O, which are X1 X2 Y1, and then the sub-list starting with X, which is X1 X2.
Object create S1
Object create X1 -mixins S1
Object create X2
Object create Y1
Object create O -mixins X1 X2 Y1
puts "[O getMixins], [O getMixins X*]"
The following code creates a mixins hierarchy and first prints all direct and indirect mixins of O, which are X1 S1 X2 Y1, and then the sub-list starting with X, which is X1 X2.
Object create S1
Object create X1 -mixins S1
Object create X2
Object create Y1
Object create O -mixins X1 X2 Y1
puts "[O getMixins -all], [O getMixins -all X*]"

getNextPath

Syntax

<objID> getNextPath ?pattern?

Description

getNextPath calculates the next path of an object following the class path linearization rules described in Section Class Hierarchy and Class Path Linearizing. It takes an optional pattern argument, which performs a pattern matching on the list of classes on the next path before returning it (for details on pattern matching see Section Pattern Matching).

Example

The following code defines a class hierarchy and first prints the next path of O, which is very simple - only its class Object. The next path of o1 is O X1 S1 Object, i.e. the combination of its classes and all the class' superclasses in the linearized order. The sub-list of this next path, starting with X, is X1.
Object create S1
Object create X1 -superclasses S1
Object create X2 -superclasses S1
Object create Y1 -superclasses S1
Object create O -superclasses X1
O create o1
puts "[O getNextPath] [o1 getNextPath] [o1 getNextPath X*]"

getObjectID

Syntax

<objID> getObjectID

Description

getObjectID returns the object ID (i.e., the Dual Value) of the object (see Section Duals). You can also use getObjectID to explicitly transform a string into an object reference.

Example

The following code preserves an object before an unname:
Object create A
set r [A getObjectID]
A unname
The following code transforms a given string list into an object list:
set stringList {Student Lecturer}
Object create Student
Object create Lecturer
Object create joe -classes Student Lecturer
set newList ""
foreach str $stringList {
    # the references are now preserved in "newList"
    append newList [$str getObjectID]
}
Lecturer unname
puts "New List: $newList"
As newList contains references, the result looks like:
New List: Student %%1

getRefCount

Syntax

<objID> getRefCount

Description

getRefCount is a helper method for debugging and inspecting garbage collection. It prints the current reference count of an object. It might get removed in future versions of Frag.

Example

The following returns the reference count of an object:
Object create o
o getRefCount

getSubclasses

Syntax

<objID> getSubclasses ?-options ...? ?pattern?
Options: -all or -direct

Description

getSubclasses returns the list of all subclasses defined for the object objID. It takes an optional pattern argument, which performs a pattern matching on the list of subclasses before returning it (for details on pattern matching see Section Pattern Matching). Per default, or when the option -direct is chosen, only the direct subclasses are returned. -all returns the list of all direct and indirect subclasses defined for the object objID (computed recursively).

Examples

The following code creates a superclass hierarchy and first prints all direct subclasses of S1, which are X1 X2 Y1, and then the sub-list starting with X, which is X1 X2.
Object create S1
Object create X1 -superclasses S1
Object create X2 -superclasses S1
Object create Y1 -superclasses S1
Object create O -superclasses X1
puts "[S1 getSubclasses], [S1 getSubclasses X*]"
The following code creates a superclass hierarchy and first prints all direct and indirect subclasses of S1, which are X1 O X2 Y1, and then the sub-list starting with X, which is X1 X2.
Object create S1
Object create X1 -superclasses S1
Object create X2 -superclasses S1
Object create Y1 -superclasses S1
Object create O -superclasses X1
puts "[S1 getSubclasses -all], [S1 getSubclasses -all X*]"

getSubtypes

Syntax

<objID> getSubtypes ?pattern?

Description

getSubtypes returns the list of all direct and indirect subtypes of the object objID (computed recursively). This includes the direct and indirect subclasses, as well as the direct and indirect classes objID is mixin of. getSubtypes takes an optional pattern argument, which performs a pattern matching on the list of subtypes before returning it (for details on pattern matching see Section Pattern Matching).

Example

The following code creates a superclass and mixin hierarchy and first prints all direct and indirect subtypes of S1, which are X1 O X2 Y1, and then the sub-list starting with X, which is X1 X2.
Object create S1
Object create X1 -mixins S1
Object create X2 -superclasses S1
Object create Y1 -superclasses S1
Object create O -superclasses X1
puts "[S1 getSubtypes], [S1 getSubtypes X*]"

getSuperclasses

Syntax

<objID> getSuperclasses ?-options ...? ?pattern?
Options: -all or -direct

Description

getSuperclasses returns the list of all superclasses defined for the object objID. It takes an optional pattern argument, which performs a pattern matching on the list of superclasses before returning it (for details on pattern matching see Section Pattern Matching). Per default, or when the option -direct is chosen, only the direct superclasses are returned. -all returns the list of all direct and indirect superclasses defined for the object objID (computed recursively).

Examples

The following code creates a superclass hierarchy and first prints all the direct superclasses of O, which are X1 X2 Y1, and then the sub-list starting with X, which is X1 X2.
Object create S1
Object create X1 -superclasses S1
Object create X2
Object create Y1
Object create O -superclasses X1 X2 Y1
puts "[O getSuperclasses], [O getSuperclasses X*]"
The following code creates a superclass hierarchy and first prints all direct and indirect superclasses of O, which are X1 S1 X2 Y1 Object, and then the sub-list starting with X, which is X1 X2.
Object create S1
Object create X1 -superclasses S1
Object create X2
Object create Y1
Object create O -superclasses X1 X2 Y1
puts "[O getSuperclasses -all], [O getSuperclasses -all X*]"

getSupertypes

Syntax

<objID> getSupertypes ?pattern?

Description

getSupertypes returns the list of all direct and indirect superclasses, as well as all direct and indirect mixins, of the object objID (computed recursively). The result is identical to the list of all mixins (as returned by getMixins -all) preprended to the list of all superclasses (as returned by getSuperclasses -all), if there is no overlap between the two lists. If a class occurs on both lists, it is only once in the list returned by getSupertypes. getSupertypes takes an optional pattern argument, which performs a pattern matching on the list of superclasses before returning it (for details on pattern matching see Section Pattern Matching).

Example

The following code creates a superclass and mixins hierarchy and first prints all direct and indirect superclasses and mixins of O, which are X1 S1 X2 Y1 Object, and then the sub-list starting with X, which is X1 X2.
Object create S1
Object create X1 -mixins S1
Object create X2
Object create Y1
Object create O -superclasses X1 X2 Y1
puts "[O getSupertypes], [O getSupertypes X*]"

getVars

Syntax

<objID> getVars ?pattern?

Description

getVars prints the list of all instance variables defined for an object. It takes an optional pattern argument, which performs a pattern matching on the list of variables before returning it (for details on pattern matching see Section Pattern Matching).

Example

The following code defines an object with 3 variables. Then it first prints the list of all variables and next all variables starting with x. The result is: {x2 x1 y1} {x2 x1}.
Object create O
O set x1 1
O set x2 2
O set y1 3
puts "[O getVars], [O getVars x*]"

isType

Syntax

<objID> isType <className>

Description

isType checks whether objID is direct or indirect instance of className. If this is true, isType returns true, otherwise false.

Example

The following code prints: false true true true true false because O is not of type X1, but of type Object. o1 is of type O, S1, and X1, but not of type X2.
Object create S1
Object create X1 -superclasses S1
Object create X2 -superclasses S1
Object create Y1 -superclasses S1
Object create O -superclasses X1
O create o1
puts [list build [O isType X1] [O isType Object]
    [o1 isType O] [o1 isType S1]
    [o1 isType X1] [o1 isType X2]]

method

Syntax

<objID> method <methodName> <args> <body code>

Description

method is used for dynamically defining a method. Methods are explained in Section Methods.

Example

A method is created on a class B and invoked on an instance b of class B:
Object create B
B method m2 {a b c} {
    return [list build ($a + 1) $b $c]
}    
B create b
puts "Invocation result: [b m2 2 2 2]"

mixins

Syntax

<objID> mixins ?<class1> ... <classN>?

Description

mixins defines a number of classes as mixins for objID. Existing mixins are overwritten. Hence mixins dynamically changes the mixins of a class. ?<class1> ... <classN>? must be existing classes; if one of those classes does not exist, an error is raised.

A class has initially an empty mixin list.

Example

The following code puts two classes as mixins on Q and prints the mixins list. After this all the mixins are removed, by providing an empty mixins list.
Object create O
Object create P
Object create Q -mixins O P
puts "mixins of Q: [Q getMixins]"
Q mixins
puts "mixins of Q: [Q getMixins]"

rename

Syntax

<objID> rename <objectName>

Description

rename renames an object by registering it under a new name in the interpreter.

Example

In the following example code, we first create an object o and then rename it to o1. Hence, o set r 1 does not work anymore after renaming, but o1 set r 1 and o1 getClasses.
Object create C1
C1 create o
o rename o1
set e1 [catch {o set r 1}]
puts "Invocations on o1: [o1 set r 1] [o1 getClasses]"

renameMethod

Syntax

<objID> renameMethod <methodName> <newMethodName>

Description

renameMethod renames a method dynamically. methodName must be an existing method of the class objID. The method is is dynamically renamed to newMethodName.

Example

The following code renames a method to a new name:
Object create ForRename
ForRename method y {} {;}
ForRename renameMethod y a
puts "methods: [ForRename getMethods]"

set

Syntax

<objID> set <var> <value>

Description

set writes an object variable var and sets its value to the given value argument. set returns the value.

Example

The following code sets a variable on object o using set and then reads it using get:
Object create o
o set r 1
puts "value of r: [o get r]"

superclasses

Syntax

<objID> superclasses <class1> ?... classN?

Description

superclasses defines a number of classes as superclasses for objID. Existing superclasses are overwritten. Hence superclasses dynamically changes the superclasses of a class. <class1> ?... classN? must be existing classes; if one of those classes does not exist, an error is raised.

An object must have at least one superclass. If no superclass is given upon creation, Object is assigned as superclass. Hence, you cannot re-superclass to nothing, but the equivalent to removing all superclasses from an object is to re-superclass it to Object.

Example

The following code puts two classes as superclasses on Q and prints the superclass list. Afterwards, the superclasses are removed, by re-superclassing to Object. This is also the superclass of the "plain" objects, like O or P, which have no special superclasses assigned.
Object create O
Object create P
Object create Q -superclasses O P
puts "superclasses of Q: [Q getSuperclasses]"
Q superclasses Object
puts "superclasses of Q: [Q getSuperclasses]"
puts "superclasses of O: [O getSuperclasses]"

unname

Syntax

<objID> unname

Description

unname tells the interpreter to forget the name of an object. create can create objects with or without name (see Section create). An object name is like a reference to the object. If the object has no reference, it gets garbage collected. Hence, unname can be used to dispose named objects, once they are no longer needed.

Unnamed objects have an automatically assigned ID, of the form: %%number, such as %%12. Once unname is called on an object, its name is forgotten, and it gets an automatically assigned ID, which is returned by unname.

Calling unname on an object without name causes an error.

Example

The code below creates a named object a, which is preserved only because of its name, but which has no further references. Then unname is called and hence the object gets garbage collected. The name a does not exist anymore, and hence the invocation a aMethod 2 causes an error.
Object create a
a unname
set e [catch {a aMethod 2}]

unset

Syntax

<objID> unset <var1> ?... varN?

Description

unset deletes one or more variables from the object's variable table. It throws an error, if the variable does not exist on the object.

Example

The following code first creates four variables on object o. Then three of these variables get deleted by unset; hence only the variable x1 remains:
Object create o -set x 3 -set y 4 -set z 5 -set x1 4
puts "Vars on o: [o getVars]"
o unset x y z
puts "Vars on o: [o getVars]"

varExists

Syntax

<objID> varExists <varName>

Description

varExists tests whether a variable varName exists as an instance variable on object objID and returns true, if it exists, and false otherwise.

Example

The following example prints true, false because x is an instance variable of O, but y is not:
Object create O
O set x 1
puts "[O varExists x], [O varExists y]"

  index | contents | previous | next