ZetCode

Tcl trace Command

last modified October 20, 2026

The Tcl trace command monitors variables (and also commands and script execution) for specific operations. This article covers variable traces. It allows executing custom scripts when variables are accessed or modified. This powerful feature enables debugging and reactive programming patterns.

Basic Definition

The trace command sets up callbacks for variable operations. These operations are read, write, unset and, for arrays, array (the use of an array command).

Syntax: trace add variable name ops command. The ops argument is a list of operations, and the command is a command prefix that Tcl calls with the variable name, the array index and the operation appended. Multiple traces can be added to the same variable.

Simple Variable Write Trace

This example demonstrates tracing write operations on a variable.

write_trace.tcl
proc traceWrite {varName index op} {
    upvar 1 $varName v
    puts "Variable $varName was modified"
    puts "New value: $v"
}

set x 10
trace add variable x write traceWrite

set x 20
set x 30

The traceWrite procedure is called whenever x is modified. It receives the variable name, array index (empty for scalars), and operation type. The procedure runs in its own scope, so it uses upvar 1 to reach the traced variable by name. This helps track all changes to the variable.

Read Operation Tracing

This example shows how to trace when a variable is read.

read_trace.tcl
proc traceRead {varName index op} {
    puts "Variable $varName was read"
}

set y 100
trace add variable y read traceRead

puts "Value: $y"
set z [expr {$y + 50}]

The traceRead procedure executes whenever y is accessed. This helps monitor all read operations, useful for debugging or implementing computed properties.

Array Element Tracing

Traces work with array elements similarly to scalar variables.

array_trace.tcl
proc arrayTrace {arrName index op} {
    upvar 1 $arrName arr
    puts "Array $arrName\($index) operation: $op"
    if {$op eq "write"} {
        puts "New value: $arr($index)"
    }
}

array set colors {red #ff0000 green #00ff00}
trace add variable colors write arrayTrace
trace add variable colors read arrayTrace

set colors(blue) #0000ff
puts $colors(green)

This traces both read and write operations on array elements. The index parameter contains the array key being accessed. The upvar 1 command is needed to access the array from the trace procedure.

Unset Operation Tracing

Traces can detect when variables are unset, including when a local variable is destroyed because its procedure returned.

unset_trace.tcl
proc traceUnset {varName index op} {
    puts "Variable $varName is being unset"
}

set temp "temporary value"
trace add variable temp unset traceUnset

unset temp

The traceUnset procedure executes after the variable has been removed, so it can no longer read the old value. This allows cleanup operations or logging when variables are destroyed.

Multiple Traces on Single Variable

Multiple traces can be added to the same variable for different operations.

multi_trace.tcl
proc writeHandler {varName index op} {
    upvar 1 $varName v
    puts "WRITE: $varName changed to $v"
}

proc readHandler {varName index op} {
    puts "READ: $varName was accessed"
}

set counter 0
trace add variable counter write writeHandler
trace add variable counter read readHandler

incr counter
set x [expr {$counter * 2}]

This example adds separate traces for read and write operations. The handlers provide different output for each operation type. The incr command reads the variable before it writes it, which is why "READ" is printed before "WRITE". If several traces match the same operation, the one added last runs first.

Removing Traces

Traces can be removed when they're no longer needed.

remove_trace.tcl
proc logChange {varName index op} {
    puts "Change detected in $varName"
}

set debugVar "test"
trace add variable debugVar write logChange

set debugVar "new value"

trace remove variable debugVar write logChange
set debugVar "no tracing now"

The trace remove command stops the tracing. After removal, variable operations no longer trigger the callback, so the last assignment prints nothing. The same arguments (operations and command) that were given to trace add are needed to remove the trace. Removing traces avoids needless overhead and unwanted side effects.

Best Practices

This tutorial covered the Tcl trace command with practical examples showing its usage for monitoring variable operations.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Tcl Tutorials.