Tcl:将所有变量从 main 传递到过程

Tcl : pass all variables from main to procedure

在我的tcl脚本中,有一部分代码重复了很多,所以我想把它做成一个程序。

关键是这部分使用了几十个变量,我想避免将它们作为参数传递给过程。有没有办法让所有变量对过程可见? (实际上,我希望 "main" 像 "goto" 一样分支到过程,然后 return 并在 main 中继续)。

已编辑:它不需要是一个程序,请随时提出其他方法。重要的部分是不需要声明所有从 main 传递到 function/procedure 的 variables/arguments。

示例:

 proc dummy_proc {} {
 set var1 $var2
 set var2 $var3
 }

 set var2 2
 set var3 3
 dummy_proc 
 puts "$var1 $var2"
 # should print "2 3"

使用global

proc dummy_proc {} {  
  global var2 var3  
  set var1 $var2  
  set var2 $var3  
}

set var2 2  
set var3 3  
dummy_proc   
puts "$var1 $var2"  

如果你有很多全局变量要传递,你可以使用一些 foreach,但是你必须有办法找到它们。
例如所有全局变量都称为 GLOBAL_<SOMEARG>

proc dummy_proc {} { 
  foreach glb [info globals GLOBAL_*] { 
    global $glb 
  } 
  ... 
}

这是可能的,但通常不可取,因为它会使代码更难阅读(没有直接指示变量来自何处或变量值如何突然变化)。但是在某些情况下,这可以减少重复代码。

使用upvar (https://www.tcl.tk/man/tcl8.6/TclCmd/upvar.htm):

proc dummy_proc {} {
    upvar var1 v1
    upvar var2 v2
    upvar var3 v3

    set v1 $v2
    set v2 $v3
}

upvar 所做的是在本地范围内创建一个变量,该变量引用调用方范围内的另一个变量。

或者您也可以尝试使用 uplevel (https://www.tcl.tk/man/tcl8.6/TclCmd/uplevel.htm):

proc dummy_proc {} {
    uplevel {
        set var1 $var2
        set var2 $var3
    }
}

uplevel 的作用与 upvar 类似,但它不是创建变量引用,而是在调用者的范围内实际执行代码。就好像你暂时回到调用者函数没有返回,执行一些代码然后回来。因为您在调用者范围内执行代码,所以在调用者范围内可见的所有变量在您升级的代码中都是可见的。 Uplevel 的行为几乎像一个宏而不是一个函数。