3.4.1.0.1 Creating TclObjects

By using []new, the user creates an interpreted TclObject. the interpreter will execute the constructor for that object, []init, passing it any arguments provided by the user. ns is responsible for automatically creating the compiled object. The shadow object gets created by the base class TclObject's constructor. Therefore, the constructor for the new TclObject must call the parent class constructor first. []new returns a handle to the object, that can then be used for further operations upon that object.

The following example illustrates the Agent/SRM/Adaptive constructor:

        Agent/SRM/Adaptive instproc init args {
                eval \$self next \$args
                \$self array set closest_ "requestor 0 repairor 0"
                \$self set eps_    [\$class set eps_]
        }

The following sequence of actions are performed by the interpreter as part of instantiating a new TclObject. For ease of exposition, we describe the steps that are executed to create an Agent/SRM/Adaptive object. The steps are:

  1. Obtain an unique handle for the new object from the TclObject name space. The handle is returned to the user. Most handles in ns have the form _oNNN, where NNN is an integer. This handle is created by getid../tclcl/tcl-object.tclTclObject::getid. It can be retrieved from C++ with the name()../tclcl/tclcl.hTclObject::name() method.
  2. Execute the constructor for the new object. Any user-specified arguments are passed as arguments to the constructor. This constructor must invoke the constructor associated with its parent class.

    In our example above, the Agent/SRM/Adaptive calls its parent class in the very first line.

    Note that each constructor, in turn invokes its parent class' constructor ad nauseum. The last constructor in ns is the TclObject constructor../Tcl/tcl-object.tclTclObject::init. This constructor is responsible for setting up the shadow object, and performing other initializations and bindings, as we explain below. It is preferable to call the parent constructors first before performing the initializations required in this class. This allows the shadow objects to be set up, and the variable bindings established.

  3. The TclObject constructor invokes the instance procedure []create-shadow for the class Agent/SRM/Adaptive.
  4. When the shadow object is created, ns calls all of the constructors for the compiled object, each of which may establish variable bindings for objects in that class, and perform other necessary initializations. Hence our earlier injunction that it is preferable to invoke the parent constructors prior to performing the class initializations.
  5. After the shadow object is successfully created, create_shadow../Tcl/Tcl.ccTclClass::create_shadow
    1. adds the new object to hash table of TclObjects described earlierSectionsec:HashTables.
    2. makes []cmd an instance procedure of the newly created interpreted object. This instance procedure invokes the []command method of the compiled object. In a later subsectionSectionsec:Commands, we describe how the command method is defined, and invoked.
Note that all of the above shadowing mechanisms only work when the user creates a new TclObject through the interpreter. It will not work if the programmer creates a compiled TclObject unilaterally. Therefore, the programmer is enjoined not to use the C++ new method to create compiled objects directly.

Tom Henderson 2011-11-05