v1- old var,v2 - new var ..目前如果有人设置v1,它将会出错,所以我将它向后兼容。因此,如果在任何地方定义了旧的var v1,我想使这两个变量相同,即v2 = v1(v1的值也应该在v2中)
设置v1测试
为此,我有一个旧名称和新名称的哈希
set oldvars(v1) v2
foreach ele [array names oldvars] {
if {([info exists ele] || $ele == "") && $oldvars($ele)!= ""} {
o2n $ele $oldvars($ele) //o2n is a proc defined below
}
}
proc o2n {gvar gval}
global v1
puts "gvar is $gvar, gval is $gval" //prints gvar - v1 and gval - v2
set $gval [set $$gvar] **//Error - Cant read $v1 no such variable. Above line does print gvar = v1 so $$gvar should be $v1 =test**
puts "$gval [set $gvar]" // Has the value of v1 i.e test
}
puts "v2 is $v2" **: Error : Can't read v2 no such variable**
答案 0 :(得分:1)
如果我们假设
set a1 1
set b1 2
set c1 3
set oldvars(a1) a2
set oldvars(b1) b2
set oldvars(c1) c2
将 x 1个变量中的值复制到相应的 x 2个变量所需要做的就是
foreach {x1 x2} [array get oldvars] {
set $x2 [set $x1]
}
分配看起来有点偏,但它的含义是“分配名称在x2
中的变量,该变量的名称在x1
中。
如果要通过过程执行此操作,则需要考虑过程的代码在另一个范围内执行。 uplevel
命令对此有所帮助,并且作为副作用,分配代码变得更简单:
proc o2n {x1 x2} {
upvar 1 $x1 v1 $x2 v2
set v2 $v1
}
foreach {x1 x2} [array get oldvars] {
o2n $x1 $x2
}
检查存在
如果以变量的形式保留对变量的引用来存储这些变量的名称,那么对存在的测试也会与通常的不同。如果你有
foreach ele [array names oldvars] {
保证变量ele
存在(只要列表不为空,它就由foreach
创建 - 但是foreach
的主体无论如何都不会被执行),但它不是您要验证的变量:它只保存您要验证的变量的名称。所以你需要像这样编写测试:
info exists $ele
(您还需要与ele
引用的变量存在于同一范围内)。
这看起来很奇怪,因为我们通常非常小心地验证变量的名称,而不是值。但在这种情况下,变量的值是我们要验证的名称,所以。
在程序中,编写测试更容易。 upvar
命令在当前作用域中创建链接到另一个作用域中的变量的名称。如果这些变量不存在,则本地名称实际上是未设置变量的名称。
upvar 1 $x1 v1 $x2 v2
if {[info exists v1]} {