我真的不懂如何使用eval
参数。
如果我想要评估的脚本是:
set myscript { puts $::argv }
然后我想这样调用我的脚本:
eval $myscript anArgument
我希望输出为" anArgument",而是我有:
can not find channel named ""
while evaluating {eval $script vvv}
答案 0 :(得分:2)
当您调用eval
时,该命令会连接其所有参数并尝试评估结果列表(或者如果您愿意,则为字符串,这与此相同)。因此,首先将参数{ puts $::argv }
和anArgument
连接到列表{puts $::argv anArgument}
中,然后解释器尝试对其进行评估。如果全局变量argv
的值是空列表,则调用的实际命令将等同于puts {} anArgument
。 puts
将尝试使用{}
作为频道标识符输出,失败并留下错误消息。
现在,如果您想要做的是将anArgument
传递给myscript
,然后将eval
传递给puts anArgument
,那么您应该写一下
set myscript {puts $myarg}
set myarg anArgument
eval $myscript
在第一行中,由于引号括号将$myarg
转换为常规文本字符,因此$
的评估被推迟。然后将变量myarg
设置为一个值(这可以在代码中的任何位置发生,只要它在eval
之前)。在第三行中,将对脚本进行求值,然后将参数$myarg
替换为值anArgument
,然后将其打印出来。
您尝试的那种调用是可能的,但是您需要使用apply
而不是eval
,以及闭包(匿名函数)而不是脚本。
set myfunc {myarg {puts $myarg}}
apply $myfunc anArgument
全局变量argv
不将参数传递给传递给eval
的脚本:当tclsh
或wish
启动时在操作系统中,给出的任何命令行参数都放在argv
中,并且在执行期间永远不会更改该值,除非您自己更改它(不要这样做,这只是令人困惑)。
argv
记录在案here。