如何从info globals命令输出所有变量的值列表?

时间:2012-05-17 23:58:30

标签: tcl

我正在尝试编写一小段代码,列出所有变量及其包含在info globals命令中的值。我已经尝试了几次替换迭代但是不能让Tcl将变量名称视为变量,并返回其值。以下是我的开始:

set fileid [open "c:/tcl variables.txt" w+]
foreach {x}  [lsort [info globals]]  {
    set y $x
    puts $fileid "$x  $y   "
}

我可以

DEG2RAD  DEG2RAD   
PI  PI   
RAD2DEG  RAD2DEG   
.....

DEG2RAD  $DEG2RAD   
PI  $PI   
RAD2DEG  $RAD2DEG   
.....

但我需要的是

DEG2RAD  0.017453292519943295   
PI  3.1415926535897931   
RAD2DEG  57.295779513082323   
....   

3 个答案:

答案 0 :(得分:4)

我认为您正在寻找subst命令:

set fileid [open "c:/tcl variables.txt" w+] 
foreach {x} [lsort [info globals]] {
  puts $fileid "$x [subst $$x] " 
}

或者,您可以利用set返回设置值的事实:

set fileid [open "c:/tcl variables.txt" w+] 
foreach {x} [lsort [info globals]] {
  puts $fileid "$x [set $x] " 
}

答案 1 :(得分:3)

执行此操作的最简单方法(因为它避免了使用临时变量乱丢输出)是使用帮助程序和upvar命令:

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"

如果你有Tcl 8.5,你可以在不创建程序的情况下这样做:

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
}}

这一切都有效,因为upvar所做的是将局部变量链接到另一个堆栈帧中的变量; #0是全局堆栈帧的名称,$varname是该上下文中变量的名称,var是要绑定的局部变量。

答案 2 :(得分:1)

数组也是变量,仅供参考,输出所有变量(包括数组):

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
  1. 我正在使用list来增强值的可读性。
  2. 可以为变量子集指定模式。它不适用于数组元素名称。
  3. 与前面的示例一致,可以使用以下内容将输出写入打开的文件:puts $fileid [ListAllGlobals]