proc proc参数可以变量

时间:2014-08-10 02:29:15

标签: tcl

我刚刚在tclsh中尝试了以下内容:

proc pp {$ag} { puts hi}
pp  whatever

令我惊讶的是,这很好用!我曾预料到语法错误,因为proc参数是一个变量。但似乎tcl很好。

然后我进行了实验:

proc pp {$ag} { puts "hi $ag"}
pp  whatever

proc pp {$ag} { puts "hi ${$ag}"}
pp  whatever

我收到了错误can't read "ag": no such variable

这让我想知道,proc的论点可以变量吗?如果没有,为什么不在第一个脚本中输出错误?

1 个答案:

答案 0 :(得分:3)

第一种情况有效,因为您从未将参数用于pp

当您调用proc命令时,将调用调用文本,就像在任何其他命令调用中一样。在所有上述情况中,第三个参数(将成为pp命令的参数列表)包含在大括号中,这意味着它不会被评估为变量,而是作为三个字符串的字符串字符:" $ ag" (即美元符号在这里只是一个常规字符)。这是一个错误,并且确实有效,而不是你想象的那样。

获取参数$ag的值有点棘手。这有效:

proc pp {$ag} {puts "hi [set {$ag}]"}

美元符号实际上只是一元set命令的语法糖。有时候美元符号不会起作用,你需要回到明确的set

但这确实有效:

proc pp {$ag} {puts "hi ${$ag}"}

所以,在你的调用中,proc的第三个参数实际上并不是一个变量评估,它只是一个。当然,您可以在调用proc

时使用实际的变量评估
set foo {bar baz}
proc qux $foo {puts $bar ; puts $baz}
qux abc def
# => abc
# => def

Tcl解释器在这里真正看到的是:

proc qux {bar baz} {puts $bar ; puts $baz}

或者你真的很疯狂:

set foa {proc qux}
set fob {bar}
lappend fob baz
set foc {puts $bar}
set fod "puts \$baz"
{*}$foa $fob [join [list $foc $fod] { ; }]

与前一次proc的调用相同。 (如果你不相信我,试试list {*}$foa $fob [join [list $foc $fod] { ; }]

这个例子看起来很奇怪,但很多时候它在程序中构造新命令实际上很有用,在这些情况下,调用中使用的文本真的很好。与任何其他命令一样,proc只是可以应用Tcl的评估规则的文本。您可以对其使用任何类型的字符串或列表操作,并连接来自各种来源的文本,甚至是用户输入(如果您可以信任它)。

文档:Tcl evaluation rules including $ and {*}joinlappendlistprocputsset