我在tcl中使用{*}
进行参数扩展,并遇到了这个问题。
#!/usr/bin/tclsh
set reset {
set count 0;
set age 24;
}
puts $reset
eval $reset; # This is working fine. Commented out the below line and tried
{*}$reset; # This is throwing error. Commented out the above line and tried.
if { [ info exists count ] && [ info exists age ] } {
puts "count & age initialzed to $count and $age"
} else {
puts "count & age not initialzed :("
}
如您所见,我已定义了重置变量,我正在使用eval
以及{*}
进行评估。
虽然eval
工作正常,但{*}
正在抛出错误
wrong # args: should be "set varName ?newValue?"
while executing
"{*}$reset"
然后我按如下方式更改了变量reset
,
set reset {
set count 0;
}
即。我删除了第二个set
语句,代码工作正常。
为什么{*}
可以正常使用一个语句而不是更多?或者我在这里缺少什么?
答案 0 :(得分:2)
命令lite eval
和uplevel
(以及while
和if
等)可以评估脚本,即由零个或多个命令调用组成的字符串/列表。当您调用{*}$reset
时,您会得到六个单词而不是一个单词,但解释器仍然需要单个命令调用。实际调用的是具有五个参数的命令set
,命令将对此不予理睬。
只要扩展只形成一个命令调用,就可以将单词扩展为多个单词:
set foo bar
# => bar
言语太少了:
set cmd set
# => set
{*}$cmd
# => wrong # args: should be "set varName ?newValue?"
太多的话:
set cmd {set foo baz ; set abc def}
# => set foo baz ; set abc def
{*}$cmd
# => wrong # args: should be "set varName ?newValue?"
恰到好处:
set cmd {set foo}
# => set foo
{*}$cmd
# => bar
set cmd {set foo baz}
# => set foo baz
{*}$cmd
# => baz
也恰到好处:
set cmd set
# => set
{*}$cmd ghi jkl
# => jkl
set cmd {set mno}
# => set mno
{*}$cmd pqr
# => pqr