4

我正在尝试编写一小段代码来列出 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   
皮皮   
RAD2DEG RAD2DEG   
......

或者

DEG2RAD $DEG2RAD   
圆周率$圆周率   
RAD2DEG $RAD2DEG   
......

但我需要的是

DEG2RAD 0.017453292519943295   
PI 3.1415926535897931   
RAD2DEG 57.295779513082323   
……   
4

3 回答 3

6

我认为您正在寻找 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] " 
}
于 2012-05-18T01:28:06.997 回答
4

执行此操作的最简单方法(因为它避免使用临时变量乱扔输出)是使用帮助程序和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是要绑定到的局部变量。

于 2012-05-18T18:19:33.870 回答
2

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

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]
于 2017-05-24T10:14:36.580 回答