Tcl upvar问题

时间:2015-08-30 08:43:35

标签: 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 $name 

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

2 个答案:

答案 0 :(得分:1)

我认为你应该做的就是咬紧牙关并改变电话。毕竟,这是一个相当简单的搜索和替换。与使用任何其他解决方案相比,代码将更加清晰。

check_file_exists name

或者,您可以在参数列表中添加另一个参数,并使用该参数传递名称,使第一个参数成为伪参数。

check_file_exists $name name

或者,如果您未使用返回值,则可以返回新值并将其分配回来:

set name [check_file_exists $name]

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

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有一些变体。)

没有其他选择是漂亮的,并且所有这些选项仍然需要您在调用时进行更改(除了最后一个,如果您只使用一个变量用于此值)。如果您坚持不这样做,那么总会有Donal的info frame解决方案,这只需要更改程序本身。

如果您需要有关这些替代方案的程序代码的帮助,请与我们联系。

答案 1 :(得分:1)

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

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
}