Tcl upvar问题

Tcl upvar问题,tcl,upvar,Tcl,Upvar,我试图在向上堆栈中使用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

我试图在向上堆栈中使用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
或者,如果未使用返回值,则可以返回新值并将其重新赋值:

set name [check_file_exists $name]
或者,您可以将新值分配给全局变量,例如过程中的值,然后将其重新分配:

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

# don't need this if you're in global scope
global theName
set theName name
check_file_exists $name
使用upvar的f.i.有一些变化

没有一个备选方案是很好的,而且所有这些方案都要求您在调用时进行更改,但最后一个除外,如果您只使用一个变量来表示此值。如果你坚持不这样做,总会有Donal的信息框架解决方案,它只需要改变过程本身


如果您需要有关这些备选方案的过程代码的帮助,请告诉我。

这相当困难;这真的不是你工作的方式。但是您可以使用info frame-1来完成这项工作。info frame-1通常用于调试,以查明当前过程是如何被调用的。但是,您需要小心,因为调用方可能正在使用命令的结果:这是一种不安全的黑客行为


如果不知道该名称,则无法修改该变量。如果该变量的名称已知,则upvar varname localname也可以执行此操作。打开一罐蠕虫。整个区域是多个高压蠕虫罐。“我不能改变已经过去的事情”通常是一种迹象,表明人们即将尝试某种严重错误的工作方式。
# don't need this if you're in global scope
global theName
set theName name
check_file_exists $name
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
}