使旧的和新的变量向后兼容

时间:2016-11-14 01:52:51

标签: scripting tcl proc

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**

1 个答案:

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

文档: arrayforeachifinfoprocsetupvar