Uwe:
Thank you so much for the very lucid explanation. I was hoping that I could use the trace mechanism to implement a garbage collection scheme. I was storing the XOTcl object name in an ordinary Tcl variable upon which I placed the unset trace. When the variable goes out of scope, the unset callback is called, and I had hoped to dereference the variable to call the XOTcl object's destroy method. However, this doesn't appear to be a good approach. Do you have any suggestions?
Jim
Uwe Zdun wrote:
Jim,
at first glance, the behavior seems ok to me. You're setting 2 traces to the local scope variable "f" which get unset in reverse order -> so the two "f" outputs should be ok.
The rhs traces "2" and "3" are for the two inner invocations. For the outer invocations, the callframe is deleted before the Trace is executed. The problem here is that Tcl does not print the error that occurs.
Consider the following plain Tcl example:
proc tracecb { name1 name2 op } { if {[catch { upvar $name1 var puts "tracecb "$name1" "$name2" "$op" "$var"" } err]} { puts $err } } proc x {a} { ::trace add variable a [list unset] ::tracecb if {$a == 0} {return} incr a -1 x $a }
x 4
This prints: tracecb "a" "" "unset" "0" tracecb "a" "" "unset" "1" tracecb "a" "" "unset" "2" tracecb "a" "" "unset" "3" can't read "var": no such variable
so you cannot rely on the "upvar" in the trace to a local scope variable.
You can try to refer to an XOTcl variable (an instance variable) with "[self] trace ..." instead.
Uwe