使新旧变量向后兼容

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

文档: array, foreach, if, info, proc, set, upvar