Re: tcl-trace



Florian.Murr@xxxxxxxxxxx wrote :
I am using tcl-trace since a very long time, but today I am baffled at
the following behaviour (may be I am just overworked ;-):

proc testeTclTrace {} {
puts "[info level 0] Tcl$::tcl_patchLevel"
set ::a 0
proc ::trc {args} { puts " [info level 0] a = [set ::a]" }
trace add variable ::a {write unset} "::trc"
incr ::a
trace add variable ::a {write unset} "::trc"
incr ::a
trace add variable ::a {write unset} "::trc"
unset ::a
}

I get the following result:

testeTclTrace Tcl8.4.13
::trc ::a {} write a = 1
::trc ::a {} write a = 2
::trc ::a {} write a = 2

Where is the 'unset'-trace call?
Why do I get the 'write'-trace multiple times? (I thought, when I
register the very same command twice, it still gets called just once?!)

No, if you define several traces, and they will all get executed. From the man page:
If there are multiple traces on a variable they are
invoked in order of creation, most-recent first. If one
trace returns an error, then no further traces are
invoked for the variable.

That's why the second incr generates two calls to trc with "write" argument. Registered traces need to be explicitely disabled using "trace remove".

About the unset callback: when the unset trace is invoked, the variable has already been unset. So, unset trace is actually called, but it fails because [set ::a] is then invalid. Try to define :

proc ::trc {args} {
if {[catch {set value [set ::a]}]} {
set value "<UNDEFINED>"
}
puts " [info level 0] a = $value"
}

and you will get, as expected:

::trc ::a {} write a = 1
::trc ::a {} write a = 2
::trc ::a {} write a = 2
::trc ::a {} unset a = <UNDEFINED>
::trc ::a {} unset a = <UNDEFINED>
::trc ::a {} unset a = <UNDEFINED

Note that unset trace is called 3 times, since you registered it 3 times.

Regards,

Eric

-----
Eric Hassold
Evolane - http://www.evolane.com/
.



Relevant Pages

  • Re: after behavior (LONGish!)
    ... get the modified code even to run. ... If I uncomment the [trace add] command and comment out the command, running the code gives the error: ... variable start, resolution, deadline, t_name unset start"" ...
    (comp.lang.tcl)
  • "array unset arrayVar", "unset arrayVar" and traces
    ... thought it would be enough to trace the operation unset on the array ... If an array is deleted by "unset arrayVar", than there is one trace ... But if an array is deleted by "array unset arrayVar", ...
    (comp.lang.tcl)
  • Re: Tcl_EventuallyFree called twice - crash; also info vars ?pattern? problem
    ... According to the docs the variable being unset should no longer exist ... once inside the trace command - and the traces should have been ... but this doesn't occur in the [namespace delete] instance. ... proc Destroy { ...
    (comp.lang.tcl)
  • Re: [incr] and counting occurrences
    ... rather than just auto-initializing the variable. ... catch {unset x} ... >>Since the default incr operation is 'take the value of the named variable, ... > not accept empty strings ...
    (comp.lang.tcl)