Hi !

There is a call in tclcallbacks.c:

Ns_TclCallbackArgProc(Tcl_DString *dsPtr, void *arg)
{
    int             ii;
    Ns_TclCallback *cbPtr = arg;

    Tcl_DStringAppendElement(dsPtr, cbPtr->script);
    for (ii = 0; ii < cbPtr->argc; ii++) {
        Tcl_DStringAppendElement(dsPtr, cbPtr->argv[ii]);
    }
}


This way of constructing Tcl script works only if the
script is a single word, like a procedure name. If the
script consists of two or more "words" then it won't.
Common examples are in OO sysytems where you would specify
the class and the object to be the callback.
Good example can be made using XOTcl like this:

Class Logger
Logger log args {
   puts stderr $args
}

  ns_logctl register "Logger log" arg1 arg2

This above would actually build the Tcl line as:

  {Logger log} arg1 arg2

and this will of course not work as Tcl will not
find the {Logger log} command.

It should have rather be:

   Logger log arg1 arg2

So the preferred way would actually look like:

    Tcl_DStringAppend(dsPtr, cbPtr->script);
    for (ii = 0; ii < cbPtr->argc; ii++) {
        Tcl_DStringAppendElement(dsPtr, cbPtr->argv[ii]);
    }

Any objections to chaging this behaviour in the current code?
I do not know if this will break anything, therefore I ask.

More...

During the general callback registration and un-registration
it would be extremely helpful if the callbakck would "know"
that is being registered or called regularily or un-registered.
This way it could perform some tasks like internal caching
of resources (on registration) or destroying the caches (on
un-registration).
So, I plan to do that with the log callbacks. For that I will
"invent" the:

typedef enum {
    unknown,
    register,
    execute,
    unregister
} Ns_CallbackOperation;

and would put this into the Ns_TclCallback structure as one
additional element. Also I would add two wrapper functions

Ns_TclCallbackSetRegister
Ns_TclCallbackSetUnregister
Ns_TclCallbackSetExecute

which will just flip the bit. This is of course not a change
we would like to propagate to existing callbacks as this will
mean breaking the compatiblity with existing scripts which is
always a pain in the neck. But we can use this in any new
callbacks that we define the [ns_logctl register] being the
obvious first candidate.

In this way the Tcl script will always be called with at least
one argument: callback operation, followed by any number of
other required arguments.

I hope I managed to bring you the whole picture.
Are there any objections or better ideas how to do that?

Cheers
Zoran


Reply via email to