Say I have this TCL code (this is a simplistic example):
proc foo {} {
set k {0}
foreach a { 1 2 3 4 } {
lappend k [ expr { [lindex $k end ] + $a } ]
}
}
I want to trace the k variable within proc foo, just as I would trace it, had it been a global or a namespace variable. How can I do that, in TCL 8.5?
Thanks.
Yes, even local variables can also be traced. It does not need to be a static/global or namespace variable.
proc trackMyVar {name element op} {
# In case of array variable tracing, the 'element' variable will specify the array index
# For scalar variables, it will be empty
if {$element != ""} {
set name ${name}($element)
}
upvar $name x
if {$op eq "r"} {
puts "Variable $name is read now. It's value : $x"
} elseif {$op eq "w"} {
puts "Variable $name is written now. New value : $x"
} elseif {$op eq "u"} {
puts "Variable $name is unset"
} else {
# Only remaining possible value is "a" which is for array variables
# For array variables, tracing will work only if they have accessed/modified with array commands
}
}
proc foo {} {
# Adding tracing for variable 'k'
trace variable k rwu trackMyVar
set k {0}
foreach a { 1 2 3 4 } {
lappend k [ expr { [lindex $k end ] + $a } ]
}
unset k; # Just added this to demonstrate 'unset' operation
}
Output
% foo
Variable k is written now. New value : 0
Variable k is read now. Its's value : 0
Variable k is written now. New value : 0 1
Variable k is read now. Its's value : 0 1
Variable k is written now. New value : 0 1 3
Variable k is read now. Its's value : 0 1 3
Variable k is written now. New value : 0 1 3 6
Variable k is read now. Its's value : 0 1 3 6
Variable k is written now. New value : 0 1 3 6 10
Variable k is unset
%
The command syntax of trace
is as follows
trace variable name ops command
Here, 'ops' indicates which operations are of interest, and is a list of one or more of the following items
which should be specified as with their first letters as arwu
. You can use whichever you are interested to track. I have used rwu
. If you want to track only read operation then use r
alone in it.
Reference : trace