Variables and References

The code example below demonstrates a couple of helper procs for working with variables and references.

namespace eval helpers {
    variable cntA 0
    variable cntB 0
    variable stepSize 1
    variable totalCalls 0

    proc updateCounters {up dn msg} {
        references up dn
        variables stepSize totalCalls 
        puts "--- $msg ---"
        incr up $stepSize
        incr dn [expr {-$stepSize}]
        incr totalCalls
    }

    updateCounters cntA cntB "Incrementing A"
    puts "A = $cntA, B = $cntB, total calls = $totalCalls"
    updateCounters cntA cntB "Incrementing A"
    puts "A = $cntA, B = $cntB, total calls = $totalCalls"
    updateCounters cntB cntA "Incrementing B"
    puts "A = $cntA, B = $cntB, total calls = $totalCalls"
    set stepSize 2
    updateCounters cntB cntA "Incrementing B"
    puts "A = $cntA, B = $cntB, total calls = $totalCalls"
}

The output is as follows:

--- Incrementing A ---
A = 1, B = -1, total calls = 1
--- Incrementing A ---
A = 2, B = -2, total calls = 2
--- Incrementing B ---
A = 1, B = -1, total calls = 3
--- Incrementing B ---
A = -1, B = 1, total calls = 4

The helper procs are shown below.

proc variables {args} {
    foreach arg $args {
        uplevel variable $arg
    }
}

proc references {args} {
    foreach arg $args {
        set otherVar [uplevel [format {set %s} $arg]]
        uplevel [format {
            unset %s
            upvar %s %s
        } $arg $otherVar $arg]
    }
}