我试图使用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
此代码将打印文件的旧名称,而不是新名称。
答案 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
}