使新旧变量向后兼容
Make old and new variables backward compatible
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**
如果我们假设
set a1 1
set b1 2
set c1 3
set oldvars(a1) a2
set oldvars(b1) b2
set oldvars(c1) c2
要将值从 x1 个变量复制到相应的 x2 个变量,您只需
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
引用的变量所在的同一范围内)。
这看起来很奇怪,因为我们通常非常小心地验证变量的 name,而不是 value。但是在这种情况下变量的值是我们要验证的名字,所以。
在程序内部编写测试更容易。 upvar
命令在当前作用域中创建名称,这些名称链接到另一个作用域中的变量。如果这些变量不存在,则局部名称实际上是未设置变量的名称。
upvar 1 $x1 v1 $x2 v2
if {[info exists v1]} {
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**
如果我们假设
set a1 1
set b1 2
set c1 3
set oldvars(a1) a2
set oldvars(b1) b2
set oldvars(c1) c2
要将值从 x1 个变量复制到相应的 x2 个变量,您只需
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
引用的变量所在的同一范围内)。
这看起来很奇怪,因为我们通常非常小心地验证变量的 name,而不是 value。但是在这种情况下变量的值是我们要验证的名字,所以。
在程序内部编写测试更容易。 upvar
命令在当前作用域中创建名称,这些名称链接到另一个作用域中的变量。如果这些变量不存在,则局部名称实际上是未设置变量的名称。
upvar 1 $x1 v1 $x2 v2
if {[info exists v1]} {