我可以使用uplevel / upvar而不必使用全局吗?

时间:2011-04-22 18:56:22

标签: tcl

所以,我正在测试一些事情,并且有一个“测试”过程如此:

proc test {arg} {
    global state
    puts "Your arg is: $arg"
    set state 1
}
test somearg
vwait state

从阅读有关uplevel和upvar的内容,有没有一种方法可以让我不必使用global,并使用其中一个选项将状态设置为“1”然后退出程序?

2 个答案:

答案 0 :(得分:3)

是的,除了vwait始终使用全局变量进行等待(严格地说,它解析全局范围内的变量名称;如果提供限定名称,则可以使用其他名称空间)。你不能做的是等待局部变量(因为事件不能在自己的调用堆栈之外看到局部变量)。也许这将在未来发生变化,但现在肯定不会。

关于global的问题,这些陈述在程序中都是有效的:

global foo
variable ::foo
upvar #0 foo foo
upvar ::foo foo
namespace upvar :: foo foo

您的代码中也有一个错误:您在等待更改之前设置状态。这无论如何都行不通,因为你必须先等待,然后在某种事件中设置状态。

答案 1 :(得分:1)

你要求两件不同的事情。首先,关于变量。你可以这样使用upvar

proc test {arg} {
    upvar #0 state state
    puts "Your arg is: $arg"
    set state 1
}

或者,更简单地说,您可以使用命名空间限定名称:

proc test {arg} {
  puts "Your arg is: $arg"
  set ::state 1
}

你问题的第二个“一半”是vwait的奇怪用法。我只想指出你的代码片段无法完成,因为你正在等待变量'state'改变,但是没有任何事件会改变状态。当您致电test时,您已经更改了它。因此,除非您设置了一个窗口/按钮或可能导致state状态更改的内容,否则您的脚本将会挂起。

值得阅读vwait的{​​{3}}和wiki