Tcl 更新问题

Tcl upvar issue

我正在尝试使用 upvar(在向上堆栈中)修改变量,但变量的值被传递给了过程,而不是变量名。

我无法更改通过的内容,因为它已在程序中广泛实施。

有没有办法以某种方式修改文件名?

proc check_file_exists {name} {
   upvar $name newName
   check_exists $name     #Do all checks that file is there
   set newName $name_1
}

check_file_exists $name
puts $name 

此代码将打印文件的旧名称,而不是新名称。

我觉得你应该硬着头皮改电话。毕竟,这是一个相当简单的搜索和替换。与使用任何其他解决方案相比,代码将更加理智。

check_file_exists name

或者,您可以将另一个参数添加到参数列表并使用它来传递名称,使第一个参数成为虚拟参数。

check_file_exists $name name

或者,如果您不使用 return 值,您可以 return 新值并将其重新分配:

set name [check_file_exists $name]

或者,您可以将新值分配给过程中的全局变量(例如 theValue),然后将 that 分配回去:

check_file_exists $name
# don't need this if you're in global scope
global theValue
set name $theValue

或者,您可以将名称分配给全局变量(例如 theName)并在过程中访问它:该过程将能够直接更新 name

# don't need this if you're in global scope
global theName
set theName name
check_file_exists $name

(此 f.i 有一些变化。使用 upvar。)

None 的备选方案很漂亮,并且所有这些备选方案仍然需要您在调用时进行更改(最后一个除外,如果您只为此值使用一个变量)。如果您坚决不这样做,总有 Donal 的 info frame 解决方案,它只需要更改程序本身。

如果您需要任何这些替代方案的过程代码方面的帮助,请告诉我。

这很难;这真的不是你应该工作的方式。 但是您可以使用info frame -1(一种通常用于调试的工具)来查明当前过程的确切调用方式。但是,您需要小心,因为调用者可能正在使用命令的结果:这是一个不安全的 hack

proc check_file_exists {name} {
    set caller [dict get [info frame -1] cmd]
    if {[regexp {^check_file_exists +$(\w+)} $caller -> varName]} {
        # OK, we were called with a simple variable name
        puts "Called with variable $varName"
    } else {
        # Complicated case! Help...
        return -code error "must be called with a simple variable's contents"
    }

    upvar 1 $varName newName
    check_exists $name
    set newName $name_1
}