使用TCL eval命令和“set”

时间:2013-04-15 09:25:02

标签: tcl eval

以下是我正在测试的代码:

proc check_eval {} {
    set cmd {set return_val {}; set return_val}
    puts "Command to evaluate : $cmd"
    uplevel eval $cmd
}

我遇到了以下问题:当我调用“check_eval”时,看起来忽略了“set return_val {}”语句。即,interpeter在调用范围中查找现有的return_val变量。 例如:

tcl>unset return_val
tcl>check_eval
Command to evaluate : set return_val {}; set return_val
can't read "return_val": no such variable
while evaluating check_eval


tcl>set return_val 556
556
tcl>check_eval
Command to evaluate : set return_val {}; set return_val
556
tcl>

另一方面,如果我在程序中替换“set return_val {}”,例如“set return_val 10000”,它将在运行时显示10000:

tcl>set return_val 556
556
tcl>check_eval
Command to evaluate : set return_val 10000; set return_val
10000
tcl>set return_val
10000

有人能解释一下这里发生了什么吗?

感谢。

1 个答案:

答案 0 :(得分:4)

您正在进行两个级别的评估/解释,首先使用uplevel然后使用eval,并且cmd脚本周围的大括号分组仅保护您免受第一个的影响。

您不需要eval,这就足够了:

uplevel $cmd

编辑evaluplevel concat:将所有参数一起添加到一个扁平字符串中并将其作为脚本评估(使用uplevel,您可以选择另一个堆栈帧来运行它)。它们不将第一个参数用作单个命令名称,将其余参数用作发送到该命令的参数。如果是这种情况,您将从eval收到一条错误消息,指出无法找到命令“set return_val {}; set return_val”。因此,您正确使用evaluplevel错误。

uplevel运行此脚本......

eval set return_val {}; set return_val

...它的方式多于一个,因为你没有列出引用(组)的论据。

在你的例子中不需要

eval,但是你需要调用单个命令uplevel,而不需要连接它的参数,当你不需要任何替换时引用静态字符串的方法,是括号:

uplevel {after 1000 {set return_val {}; set return_val}}

...以及使用替换值引用动态字符串的方法是使用list

set cmd {set return_val {}; set return_val}
uplevel [list after 1000 $cmd]