-1

我试图使用 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 

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

4

2 回答 2

1

这是相当困难的;这真的不是你应该工作的方式。但是您可以使用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
}
于 2015-08-30T11:32:03.813 回答
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

(此 fi 使用 有一些变化upvar。)

没有一个替代方案是漂亮的,并且所有替代方案仍然需要您在调用时进行更改(除了最后一个,如果您只使用一个变量作为该值)。如果您坚持不这样做,总有 Donal 的info frame解决方案,它只需要更改程序本身。

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

于 2015-08-30T08:55:59.123 回答