重命名全局数组 TCL
Rename a global array TCL
我有一个需要重命名的全局数组,但似乎无法正确命名。
array set DataReturn {
red 1
green 5
blue 4
white 9
}
proc _RenameArray {Arr NewArrName} {
global $NewArrName
upvar #0 $Arr $NewArrName
array unset $Arr
}
_RenameArray DataReturn TheArr
我知道我在这里遗漏了很多东西。任何帮助将不胜感激!
我的头在桌子上撞了一会儿,我明白了。
proc _RenameArray {Arr NewArrName} {
global [subst $NewArrName];
upvar #0 $Arr Temp;
foreach {Key Value} [array get Temp] {
set [subst $NewArrName]($Key) $Value
}
uplevel #0 array unset $Arr
}
谁知道更好的方法,我洗耳恭听!
可以简化为:
proc _RenameArray {Arr NewArrName} {
upvar $Arr Temp
global $NewArrName
array set $NewArrName [array get Temp]
uplevel #0 array unset Temp
}
视情况而定。 Tcl 变量不能重命名,不是真的,但实际上它们可以有多个名称。你用 upvar
制作它们。特别是,upvar 0
将为当前范围内的变量赋予另一个名称。
upvar 0 DataReturn TheArr
在幕后,这使得 TheArr
成为 linked 变量;它的实际内容是指向另一个变量(当然可以是数组)的指针,但是对 linked 变量的任何操作都会转换为对基础变量的操作(除了更改 link 指向其他东西)。这不是重命名的唯一方法是原始变量仍然存在并且无法删除。
如果不能这样做,唯一的选择是将变量复制到另一个变量,unset
复制原始变量。这对于简单变量来说是微不足道的:
set TheNew $TheOld
unset TheOld
数组只是稍微复杂一点:
array set TheNew [array get TheOld]
unset TheOld
但是,这不会将 link 的变量保留到数组中,或设置的任何跟踪。复制删除与重命名不同。
将事物转化为过程稍微复杂一些,因为变量名称解析对执行它的上下文很敏感。因此,可能需要注意 upvar
和 uplevel
。我不会讨论这些选项;操作的核心就是我上面所说的,但是它们是以上下文相关的方式完成的("#0"
是在引号中,因为这里的语法高亮):
proc RenameGlobalVariable {OldName NewName} {
uplevel "#0" [list upvar 0 $OldName $NewName]
}
proc RenameGlobalSimpleVariable {OldName NewName} {
upvar "#0" $OldName old $NewName new
set new $old
unset old
}
proc RenameGlobalArray {OldName NewName} {
upvar "#0" OldName old $NewName new
array set new [array get old]
unset old
}
我有一个需要重命名的全局数组,但似乎无法正确命名。
array set DataReturn {
red 1
green 5
blue 4
white 9
}
proc _RenameArray {Arr NewArrName} {
global $NewArrName
upvar #0 $Arr $NewArrName
array unset $Arr
}
_RenameArray DataReturn TheArr
我知道我在这里遗漏了很多东西。任何帮助将不胜感激!
我的头在桌子上撞了一会儿,我明白了。
proc _RenameArray {Arr NewArrName} {
global [subst $NewArrName];
upvar #0 $Arr Temp;
foreach {Key Value} [array get Temp] {
set [subst $NewArrName]($Key) $Value
}
uplevel #0 array unset $Arr
}
谁知道更好的方法,我洗耳恭听!
可以简化为:
proc _RenameArray {Arr NewArrName} {
upvar $Arr Temp
global $NewArrName
array set $NewArrName [array get Temp]
uplevel #0 array unset Temp
}
视情况而定。 Tcl 变量不能重命名,不是真的,但实际上它们可以有多个名称。你用 upvar
制作它们。特别是,upvar 0
将为当前范围内的变量赋予另一个名称。
upvar 0 DataReturn TheArr
在幕后,这使得 TheArr
成为 linked 变量;它的实际内容是指向另一个变量(当然可以是数组)的指针,但是对 linked 变量的任何操作都会转换为对基础变量的操作(除了更改 link 指向其他东西)。这不是重命名的唯一方法是原始变量仍然存在并且无法删除。
如果不能这样做,唯一的选择是将变量复制到另一个变量,unset
复制原始变量。这对于简单变量来说是微不足道的:
set TheNew $TheOld
unset TheOld
数组只是稍微复杂一点:
array set TheNew [array get TheOld]
unset TheOld
但是,这不会将 link 的变量保留到数组中,或设置的任何跟踪。复制删除与重命名不同。
将事物转化为过程稍微复杂一些,因为变量名称解析对执行它的上下文很敏感。因此,可能需要注意 upvar
和 uplevel
。我不会讨论这些选项;操作的核心就是我上面所说的,但是它们是以上下文相关的方式完成的("#0"
是在引号中,因为这里的语法高亮):
proc RenameGlobalVariable {OldName NewName} {
uplevel "#0" [list upvar 0 $OldName $NewName]
}
proc RenameGlobalSimpleVariable {OldName NewName} {
upvar "#0" $OldName old $NewName new
set new $old
unset old
}
proc RenameGlobalArray {OldName NewName} {
upvar "#0" OldName old $NewName new
array set new [array get old]
unset old
}