3.4.4 command Methods: Definition and Invocation

For every TclObject that is created, ns establishes the instance procedure, []cmd, as a hook to executing methods through the compiled shadow object. The procedure []cmd invokes the method []command of the shadow object automatically, passing the arguments to []cmd as an argument vector to the []command method.

The user can invoke the []cmd method in one of two ways: by explicitly invoking the procedure, specifying the desired operation as the first argument, or implicitly, as if there were an instance procedure of the same name as the desired operation. Most simulation scripts will use the latter form, hence, we will describe that mode of invocation first.

Consider the that the distance computation in SRM is done by the compiled object; however, it is often used by the interpreted object. It is usually invoked as:

        \$srmObject distance? \tup{agentAddress}
If there is no instance procedure called distance?, the interpreter will invoke the instance procedure []unknown, defined in the base class TclObject. The unknown procedure then invokes
        \$srmObject cmd distance? \tup{agentAddress}
to execute the operation through the compiled object's []command procedure.

Ofcourse, the user could explicitly invoke the operation directly. One reason for this might be to overload the operation by using an instance procedure of the same name. For example,

        Agent/SRM/Adaptive instproc distance? addr {
                \$self instvar distanceCache_
                if ![info exists distanceCache_(\$addr)] {
                        set distanceCache_(\$addr) [{\bfseries{}\$self cmd distance? \$addr}]
                }
                set distanceCache_(\$addr)
        }

We now illustrate how the []command method using []ASRMAgent::command as an example.

        int ASRMAgent::command(int argc, const char*const*argv) {
                Tcl& tcl = Tcl::instance();
                if (argc == 3) {
                        if (strcmp(argv[1], "distance?") == 0) {
                                int sender = atoi(argv[2]);
                                SRMinfo* sp = get_state(sender);
                                tcl.tesultf("%f", sp-\>distance_);
                                return TCL_OK;
                        }
                }
                return (SRMAgent::command(argc, argv));
        }
We can make the following observations from this piece of code: In our document, we call operations executed through the []command instproc-likes. This reflects the usage of these operations as if they were OTcl instance procedures of an object, but can be very subtly different in their realisation and usage.

Tom Henderson 2011-11-05