Reputation: 41
I am trying to write a small bit of code that will list all of the variables and the values they contain in the info globals command. I have tried several iterations of substitution but cant get Tcl to treat the variable name as a variable, and return its value. Below is what I started with:
set fileid [open "c:/tcl variables.txt" w+]
foreach {x} [lsort [info globals]] {
set y $x
puts $fileid "$x $y "
}
I can get
DEG2RAD DEG2RAD PI PI RAD2DEG RAD2DEG .....
or
DEG2RAD $DEG2RAD PI $PI RAD2DEG $RAD2DEG .....
but what I need is
DEG2RAD 0.017453292519943295 PI 3.1415926535897931 RAD2DEG 57.295779513082323 ....
Upvotes: 4
Views: 10148
Reputation: 31
Arrays are variables too so just for reference, this outputs all variables (including arrays):
proc ListAllGlobals {{?pattern? *}} {
foreach {name} [lsort [info globals ${?pattern?}]] {
upvar {#0} $name var
if {[array exists var]} {
foreach {key val} [array get var] {
puts "${name}($key) [list $val]"
}
} else {
puts "$name [list $var]"
}
}
}
ListAllGlobals
ListAllGlobals tcl_platform
list
to enhanced readability of the values.puts $fileid [ListAllGlobals]
Upvotes: 3
Reputation: 137567
The easiest method for doing this (because it avoids littering the output with your temporary variables) is to use a helper procedure and the upvar
command:
proc listAllGlobals {filename} {
set fileid [open $filename w+]
foreach varname [lsort [info globals]] {
upvar "#0" $varname var
if {[array exists var]} continue; # Skip global arrays...
puts $fileid "$varname $var "
}
close $fileid
}
listAllGlobals "C:/tcl variables.txt"
If you've got Tcl 8.5, you can do this without creating a procedure:
apply {{} {
set fileid [open "C:/tcl variables.txt" w+]
foreach varname [lsort [info globals]] {
upvar "#0" $varname var
if {[array exists var]} continue; # Skip global arrays...
puts $fileid "$varname $var "
}
close $fileid
}}
This all works because what upvar
does is link a local variable to a variable in another stack frame; #0
is the name of the global stack frame, $varname
is the name of the variable in that context, and var
is the local variable to bind to.
Upvotes: 4
Reputation: 873
I think you are looking for the subst command:
set fileid [open "c:/tcl variables.txt" w+]
foreach {x} [lsort [info globals]] {
puts $fileid "$x [subst $$x] "
}
Alternatively, you can take advantage of the fact that set returns the value being set:
set fileid [open "c:/tcl variables.txt" w+]
foreach {x} [lsort [info globals]] {
puts $fileid "$x [set $x] "
}
Upvotes: 7