Tcl 大括号引用:大括号内的所有内容都是文字吗?
Tcl brace quoting: is everything literal inside braces?
我读过,braace {}
中的所有内容都是文字(Tcl 中的反斜杠换行符除外。
所以,这是预期的:
% puts {\{}
\{
但是,我没有正确理解以下内容:
% puts { {}
<waits for close brace>
我希望它打印 {
,因为它在大括号内,应该按字面意思理解。我期望的是:一旦遇到左括号,就按字面意思理解所有内容,直到遇到第一个右括号。但这似乎并没有发生。请解开我的误会。
对于 Tcl
程序员来说,大括号总是乞讨时的噩梦。
如您所知,大括号的主要经验法则如下,
规则 1:大括号内没有替换发生
除上述规则外,我们在 Tcl
.
中还有一些其他规则
大括号最重要的用途之一是defer evaluation
。
规则 2:延迟评估
这意味着 Tcl
解析器不会立即处理特殊字符。
相反,它们将作为参数的一部分传递给命令过程,命令过程将自行处理特殊字符。将脚本传递给 Tcl
命令时几乎总是使用大括号,如下例计算五的阶乘:
set result 1
set i 5
while {$i > 0} {
set result [expr $result*$i]
set i [expr $i-1]
}
while
循环体用大括号括起来以延迟替换。 While
将脚本传回 Tcl
以在循环的每次迭代期间进行评估,届时将执行替换。在这种情况下,延迟替换很重要,这样每次 while 计算循环体时它们都会重新完成,而不是在解析 while 命令时一劳永逸。
规则 3:大括号嵌套。 proc
命令的最后一个单词在第一行的左大括号之后开始,并包含直到右大括号的所有内容最后一行。
规则 4:Tcl 解释器移除外括号并将它们之间的所有内容(包括几对嵌套的括号)作为参数传递给 proc
。
proc power {base p} {
set result 1
while {$p > 0} {
set result [expr $result*base]
set p [expr $p-1]
}
return $result
}
在上面的例子中,proc
的第三个参数包含两对嵌套大括号(最外面的大括号被 Tcl
解析器移除)。当解析 proc
命令时,甚至当 while
命令被解析为执行过程主体的一部分时,将不会执行使用 [expr $p-1]
请求的命令替换,但仅当 while
评估其第二个参数以执行循环。
规则 5:如果大括号是反斜杠,则它不计入大括号中包含的单词的匹配右大括号的结尾。解析单词时不会删除反斜杠。
如规则 4 中所述,在代码 puts {\{}
中,删除外括号后,我们只有 \{
。这将传递给 puts
命令。现在,根据规则 5,在 \{
中,当 Tcl
遇到反斜杠左大括号时,它不会尝试匹配右大括号。此外,解析时不会删除该反斜杠。这就是 \{
在控制台中打印的原因。
在 puts {{}
的情况下,Tcl 解释器显然会等待右大括号,因为它是不平衡的。
注意:所有地方都会出现异常。好吧,Tcl
在大括号方面也一样。我们开始说大括号内没有替换。但是,大括号之间出现的唯一替换形式是反斜杠换行符。
在Tcl
中,backslash
也用于续行。
if 1 {
puts "Brace Yourself!!!"
}
你可以把上面的改写成
if 1 \
{
puts "Brace Yourself!!!"
}
同理,使用反斜杠换行,替换将如下所示。
puts {Thanks to\
Whosebug}
代码的输出将显示在一行中。
大括号嵌套(除非引用)在大括号内,因为这是规则(Dodekalogue 中的 [6])。这条规则的原因是大括号单词的内容通常是一个结构化的表达式,带有几个左括号和右括号,甚至很可能是几个 levels 的左括号和右括号。当您没有使用大括号来构建表达式时,让解析器抱怨不平衡大括号的好处超过了必须引用大括号的麻烦。
我读过,braace {}
中的所有内容都是文字(Tcl 中的反斜杠换行符除外。
所以,这是预期的:
% puts {\{}
\{
但是,我没有正确理解以下内容:
% puts { {}
<waits for close brace>
我希望它打印 {
,因为它在大括号内,应该按字面意思理解。我期望的是:一旦遇到左括号,就按字面意思理解所有内容,直到遇到第一个右括号。但这似乎并没有发生。请解开我的误会。
对于 Tcl
程序员来说,大括号总是乞讨时的噩梦。
如您所知,大括号的主要经验法则如下,
规则 1:大括号内没有替换发生
除上述规则外,我们在 Tcl
.
大括号最重要的用途之一是defer evaluation
。
规则 2:延迟评估
这意味着 Tcl
解析器不会立即处理特殊字符。
相反,它们将作为参数的一部分传递给命令过程,命令过程将自行处理特殊字符。将脚本传递给 Tcl
命令时几乎总是使用大括号,如下例计算五的阶乘:
set result 1
set i 5
while {$i > 0} {
set result [expr $result*$i]
set i [expr $i-1]
}
while
循环体用大括号括起来以延迟替换。 While
将脚本传回 Tcl
以在循环的每次迭代期间进行评估,届时将执行替换。在这种情况下,延迟替换很重要,这样每次 while 计算循环体时它们都会重新完成,而不是在解析 while 命令时一劳永逸。
规则 3:大括号嵌套。 proc
命令的最后一个单词在第一行的左大括号之后开始,并包含直到右大括号的所有内容最后一行。
规则 4:Tcl 解释器移除外括号并将它们之间的所有内容(包括几对嵌套的括号)作为参数传递给 proc
。
proc power {base p} {
set result 1
while {$p > 0} {
set result [expr $result*base]
set p [expr $p-1]
}
return $result
}
在上面的例子中,proc
的第三个参数包含两对嵌套大括号(最外面的大括号被 Tcl
解析器移除)。当解析 proc
命令时,甚至当 while
命令被解析为执行过程主体的一部分时,将不会执行使用 [expr $p-1]
请求的命令替换,但仅当 while
评估其第二个参数以执行循环。
规则 5:如果大括号是反斜杠,则它不计入大括号中包含的单词的匹配右大括号的结尾。解析单词时不会删除反斜杠。
如规则 4 中所述,在代码 puts {\{}
中,删除外括号后,我们只有 \{
。这将传递给 puts
命令。现在,根据规则 5,在 \{
中,当 Tcl
遇到反斜杠左大括号时,它不会尝试匹配右大括号。此外,解析时不会删除该反斜杠。这就是 \{
在控制台中打印的原因。
在 puts {{}
的情况下,Tcl 解释器显然会等待右大括号,因为它是不平衡的。
注意:所有地方都会出现异常。好吧,Tcl
在大括号方面也一样。我们开始说大括号内没有替换。但是,大括号之间出现的唯一替换形式是反斜杠换行符。
在Tcl
中,backslash
也用于续行。
if 1 {
puts "Brace Yourself!!!"
}
你可以把上面的改写成
if 1 \
{
puts "Brace Yourself!!!"
}
同理,使用反斜杠换行,替换将如下所示。
puts {Thanks to\
Whosebug}
代码的输出将显示在一行中。
大括号嵌套(除非引用)在大括号内,因为这是规则(Dodekalogue 中的 [6])。这条规则的原因是大括号单词的内容通常是一个结构化的表达式,带有几个左括号和右括号,甚至很可能是几个 levels 的左括号和右括号。当您没有使用大括号来构建表达式时,让解析器抱怨不平衡大括号的好处超过了必须引用大括号的麻烦。