我将在这里使用Perl作为比较:
$foo = 5;
print $foo;
将变量$foo
设置为5,然后打印变量的内容(注意$foo
始终作为$foo
访问)。
在Tcl:
set foo 5
puts $foo
与Perl对应物做同样的事情。
为什么Tcl没有用“$”设置变量,但需要“$”才能访问变量?
为什么程序也是如此(例如proc bar {spam eggs} {...}
)?
对我来说,Tcl代码看起来像这样(在伪代码中):
"foo" = 5 # Setting a string?
puts $foo # "$foo" is not defined.
(我的评论只反映了似乎正在发生的事情,而不是正在发生的事情)。
我想补充的另一点是清晰度:
set foo foo
是的,我总是可以set foo "foo"
,但set $foo foo
更不一致吗?
据我所知,“foo”可以是变量或字符串,具体取决于具体情况,如我上一个例子(set foo foo
= set var string
)所示,但我没有得到这种语法(也许是因为我习惯了Python ......)
答案 0 :(得分:13)
我认为原始Tcl只有set
命令,因此获取变量“foo”内容的唯一方法是调用set foo
。但随着Tcl进入通用脚本语言领域(回想一下,Tcl被设想为一种可嵌入的语言,你使用薄层Tcl而不是用C语言编写的编译组件,因此预计不会使用大量变量),认为$ varname语法糖是有用的,所以它被添加了。
换句话说,Tcl不像Perl那样使用“$”,其中“$”表示“将后面的任何内容解释为标量”,Tcl中的“$”也不表示变量。相反,它只是一个语法糖,“给我一个变量的值,其名称由紧接着的单词给出。”
答案 1 :(得分:12)
好吧,我决定评论原始问题的最后几点,但评论超出了限制,因此即使它没有解决指出的问题,我也会将其作为答案发布。我希望它会澄清一些似乎在问题中隐含的事情。
关于set foo foo
的一致性的说明:你以某种错误的方式接近Tcl。 Tcl与Perl或Python完全不同,因为它几乎没有语法(实际上,就像LISP一样)。 “set foo foo”不是设置变量的语法,因为它可能是另一种语言,它是一个名为“set”的命令当前的调用,并传递两个参数 - “ foo“和”foo“;它是在“set”命令名下注册的任何内容,决定变量的名称是什么以及将其设置为什么值。同样,循环命令不是语法,而是命令。真的,值得停下来思考
for {set i 0} {$i < 10} {incr i} {
puts $i
}
不仅仅是一个异想天开的语言设计者的想法,而是使用大括号,或者像C中的“普通”括号。相反,这里Tcl解析器解析出五个单词,将第一个单词作为命令的名称,看起来它,并将其余的词传递给它;它是for
的实现,它解释那些{set i 0}
,{$i < 0}
等并适当地执行它们。语法仅用于指定如何从输入的字符流中解析出单词。而且由于所有内容都是使用命令实现的,因此您的命令与内置命令的行为没有区别;这允许您创建与for
或switch
一样强大的自定义命令(类似于LISP中的宏)。在另一种语言中,这将等于以任意方式扩展sytnax的能力。
当这个想法“点击”时,Tcl将不再显得奇怪。 而且这个属性使得Tcl易于扩展(并且可嵌入):因为你从C端提供的命令与所有内置命令完全相同。
答案 2 :(得分:3)
将$foo
视为变量foo
的值,即上次设置的文本。现在,如果foo
目前的值为x
,则set $foo y
表示set x y
,这显然不是什么意思。它实际上比其他语言更加一致,其中foo
有时表示变量foo
的值,有时表示变量foo
本身。
答案 3 :(得分:2)
真正的答案,如果有的话,只能由原始语言设计师(John Ousterhout)给出。所以其余部分对投机或(受过教育的)猜测持开放态度。 TCL有一些历史可供here,但快速阅读后没有直接答案。
为什么Tcl不使用&#34; $&#34;设置变量,但需要&#34; $&#34;访问一个 变量?
我的看法是,它与(UNIX)shell语言更紧密地对齐。 TCL是在伯克利构思的,可以说是一个强大的UNIX(或者就此而言就是BSD)环境。
在声明或分配变量时,UNIX shell也不会使用$符号(或相应shell的等效符号),但在引用变量时需要它:
# bourn shell like shells (sh, bash, ksh, ...)
foo=foo
echo "The value of the variable foo is $foo."
即使是不圣洁的Windows CMD.EXE处理器也使用了类似的方法(虽然我猜 不是TCL设计师的想法; - )
REM DOS COMMAND.COM / Windows CMD.EXE
set foo=foo
echo The value of the variable is %foo%.
此外,&#34;字符串值&#34; (虽然shell是众所周知的弱类型)如果字符串值中现在有空格,通常不需要引号。
是的,我总是可以设置foo&#34; foo&#34;,但是不能设置$ foo foo更多 一致?
嗯,对于TCL设计师/创作者来说并非如此; - )
编辑我差点忘了:您实际上可以在TCL中执行以下操作:
set foo bar
set $foo something
puts $bar
这实际上会输出&#34;某些东西&#34;。第二行实际上设置字符串&#34;&#34;到变量&#34; foo&#34;的值,从而设置一个名为&#34; bar&#34;的变量。并为其分配价值&#34;&#34;。