Sharing lots of values in Tcl without having lots of global declarations
Archive - Originally posted on "The Horse's Mouth" - 2012-02-28 21:06:51 - Graham EllisQ: How can I make a lot of values defined in my Tcl main program available in various procs, without having to pass them all down the chain or declare them as global all over the place?
A question from today's Tcl course - to which my first reaction was "why do you want to do that?". However, having heard a plausible explanation, I set about providing an answer, and in the end I came up with two variants.
Both solutions hinge around an array of values in the global (top level) scope, which are to be referenced by simple variable names within any proc that needs them, those variable names being the words used as keys in the array. So in my top level code I have:
set share(town) Dublin
which means I want to be able to write
set response "I'm in $town "
within a proc, and be able to do the same thing with lots of other settings too.
The "trick" is to provide a proc - let's call it loadshares - which I can call within any other proc which needs to access these variables. And have loadshares use uplevel to set individual variables, in a loop, within the proc it's called from.
Here is my first implementation of loadshares, which copies the values to new local variables so they are available READ ONLY:
proc loadshares {} {
global share
foreach key [array names share] {
uplevel set $key $share($key)
}
}
Complete source code of the example, and sample output, [here].
The second implementation of loadshares uses upvar within uplevel, so it's creating a new local name (an alias) for each variable in the array. The effect of this into mae the local variables READ / WRITE - in other words, any changes made effect the global array:
proc loadshares {} {
global share
foreach key [array names share] {
uplevel "upvar #0 share($key) $key"
}
}
Complete source code of the example, and sample output, [here].
Remember - just because I've told you how to do this doesn't mean that you should rush out and do it. I'm convinced that it's a sensible technique in the right circumstances, but circumstances may be few and far between.