Home > Archive > Tcl > November 2006 > tcl-trace
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
|
|
| Florian.Murr@siemens.com 2006-11-28, 7:11 pm |
| 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?!)
regards,
- Florian
| |
|
| I am a noob, so please forgive me if I am wrong.
It seems to me that this is what's happening:
> proc testeTclTrace {} {
> puts "[info level 0] Tcl$::tcl_patchLevel"
> set ::a 0 -- value of ::a == 0
> proc ::trc {args} { puts " [info level 0] a = [set ::a]" }
> trace add variable ::a {write unset} "::trc" -- trace setup on ::a
> incr ::a -- ::a incremented to 1, then the trace kicks in and calls ::trc which prints the value of ::a, i.e. 1
> trace add variable ::a {write unset} "::trc"
> incr ::a -- exactly similar to above, only this time ::a is incremented to 2 and then printed.
> trace add variable ::a {write unset} "::trc"
> unset ::a -- the trace kicks in before the variable is unset, so it still has a value, i.e. 2. So 2 gets printed.
> }
There are others far smarter than me who can doubtless find holes in
this explanation.
Cheers,
Diptansu
| |
| Florian.Murr@siemens.com 2006-11-29, 4:09 am |
| >...No, if you define several traces, and they will all get executed. ...
> That's why the second incr generates two calls to trc with "write"
> argument. Registered traces need to be explicitely disabled using "trace
> remove".
Yes, I concluded that much my self, but I thought that in some previous
Tcl version the behaviour when registering the VERY SAME command twice,
was different.
It is not a problem, once you know it.
> trace returns an error, then no further traces are
> invoked for the variable.
> ...
> 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 :
>
Thanks a lot! - So simple, I just overlooked the error in the
trace-callback.
regards,
- Florian
| |
| Florian.Murr@siemens.com 2006-11-29, 4:09 am |
| Thanks for trying to help me!
Your explanation is not correct however. (A correct explanation is
below in the discussion)
In Tcl, traces hit like a stroke of lightning!
They do not come 'after idle' or the like, but in the very instant a
variable is 'set', or 'unset'.
The problem with this behaviour is, that you often get very cryptic
error-messages, or in our case none at all!
To get better error-messages, I often trace like this:
trace add variable ::a {write unset} [linsert $cmd 0 after idle]
I just forgot all that, because I was too overworked.
regards,
- Florian
|
|
|
|
|