为什么 Tcl 在调用“set”时不在变量名前使用美元符号?
我将在这里使用 Perl 进行比较:
$foo = 5;
print $foo;
将变量 $foo
设置为 5,然后打印变量的内容(请注意,$foo
始终被访问如$foo
)。
在 Tcl 中:
set foo 5
puts $foo
与 Perl 的对应部分执行相同的操作。
为什么Tcl不使用“$”设置变量,而是需要“$”来访问变量? 为什么程序也是如此(例如proc bar {spam Egg} {...}
)? 对我来说,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......)
I am just going to use Perl as a comparison here:
$foo = 5;
print $foo;
sets the variable $foo
to 5, and then prints the contents of the variable (notice that $foo
is always accessed as $foo
).
In Tcl:
set foo 5
puts $foo
does the same thing as the Perl counterpart.
Why doesn't Tcl set variables with the "$", but need a "$" to access a variable?
Why is this true for procedures too (e.g.proc bar {spam eggs} {...}
)?
To me, the Tcl code looks like this (in pseudocode):
"foo" = 5 # Setting a string?
puts $foo # "$foo" is not defined.
(my comments only reflect what appears to be happening, not what is happening).
Another point I want to add is the clarity of this:
set foo foo
Yeah, I could always do set foo "foo"
, but isn't set $foo foo
more consistent?
From what I know, "foo" can be a variable or a string, depending on the situation, as seen in my last example (set foo foo
= set var string
), but I don't get this syntax (maybe because I'm used to Python...)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我认为原始的 Tcl 只有
set
命令,因此获取变量“foo”内容的唯一方法是调用set foo
。但随着 Tcl 进入通用脚本语言领域(回想一下,Tcl 被设想为一种可嵌入语言,您可以在用 C 编写的复杂组件上使用一层薄薄的 Tcl,因此预计不会使用大量变量),认为 $varname 语法糖很有用,所以添加了它。换句话说,Tcl 不像 Perl 那样使用“$”,其中“$”的意思是“将后面的任何内容解释为标量”,Tcl 中的“$”也不表示变量。相反,它只是“给我一个变量的值,该变量的名称由紧随其后的单词给出”的语法糖。
I think the original Tcl only had the
set
command, so the only way to fetch the contents of a variable "foo" was callingset foo
. But as Tcl progressed into the domain of general-purpose scripting languages (recall that Tcl was envisioned as being an embeddable language where you use a thin layer of Tcl over compilcated components written in C, so one wasn't expected to use lots of variables), it was deemed that that $varname syntactic sugar is useful and so it was added.In other words, Tcl does not use "$" in the same way as Perl does, in which the "$" means "interpret whatever follows as a scalar", neither does "$" in Tcl denote a variable. Instead it merely a syntactic sugar for "give me the value of a variable whose name is given by the immediately following word".
好吧,我决定对原始问题的最后一点进行评论,但评论超出了限制,因此即使它没有解决指定的问题,我也会将其作为答案发布。我希望它能澄清问题中似乎暗示的一些事情。
关于
set foo foo
一致性的注意事项:您正在以某种错误的方式接近 Tcl。 Tcl 与 Perl 或 Python 完全不同,因为它几乎没有语法(真的,就像 LISP)。 “set foo foo”不是用于设置变量的语法,因为它可以在另一种语言中使用,它是对当前在名称“set”下可用的命令的调用,并向其传递两个参数--” foo”和“foo”;它是在“set”命令名称下注册的任何内容,决定变量的名称是什么以及将其设置为什么值。同样,循环命令不是语法,而是命令。真的,值得在这里停下来,认为这不仅仅是一个异想天开的语言设计者的想法,用大括号代替或像 C 中那样的“正常”括号。相反,这里 Tcl 解析器解析出五个单词,将第一个单词作为命令的名称,查找它,然后传递其余的单词;它是
for
的实现,它解释那些{set i 0}
,{$i <; 0}
等并适当地执行它们。语法仅用于指定如何从字符输入流中解析出单词。由于一切都是使用命令实现的,因此您的命令的行为与内置命令没有什么不同;这允许您创建与for
或switch
一样强大的自定义命令(类似于 LISP 中的宏)。在另一种语言中,这相当于以任意方式扩展 sytnax 的能力。当这个想法“咔嚓”一声时,Tcl将不再显得怪异。
正是这个属性使得 Tcl 如此容易扩展(和嵌入):因为您从 C 端提供的命令的行为与所有内置命令完全相同。
Well, I decided to comment upon the last bits of the original question, but the comment overgrown the limit, and so I'll post it as an answer even while it does not address the indicated question. I'll hope it will clarify some things which appear to be implied in the question though.
A note about the consistency of
set foo foo
: you're approaching Tcl in a somewhat wrong way. Tcl is radically different from Perl or Python in that it has almost no syntax (really, like LISPs). "set foo foo" is not a syntax for setting a variable as it could be in another language, it's a call to a command currently available under the name "set" and passing it two arguments--"foo" and "foo"; it's whatever is registered under the "set" command name decides what is the name of a variable and what is the value to set it to. Likewise, looping commands are not syntax, they are commands. Really, it worth stopping here and think thatis not merely a whimsical language designer's idea to go with curly braces instead or "normal" parentheses like in C. Instead, here the Tcl parser parses out five words, takes the first one to be the name of a command, looks it up, and passes it the rest of the words; it's the implementation of
for
which interprets those{set i 0}
,{$i < 0}
etc and executes them appropriately. The syntax is there only to specify how there words are parsed out from the input stream of characters. And since everything is implemented using commands, your commands are able to behave no different from builtin ones; this allows you to create custom commands as powerful asfor
orswitch
(something akin to macros in LISPs). In another language this would be equal to the ability to extend sytnax in arbitrary ways.When this idea "clicks" , Tcl will no longer appear to be weird.
And it's this property which makes Tcl so easily extensible (and embeddable): because the commands you provide from your C side behave absolutely the same as all builtin commands.
将
$foo
视为变量foo
的值,即最后设置的文本。现在,如果foo
当前的值为x
,则set $foo y
表示set x y
,这显然不是是什么意思。它实际上比其他语言更加一致,其中foo
有时表示变量foo
的值,有时表示变量foo
本身。Think of
$foo
as meaning the value of the variablefoo
, ie the text which it was last set to. Now, iffoo
currently has the valuex
,set $foo y
meansset x y
, which is clearly not what is meant. It is actually more consistent than other languages, wherefoo
sometimes means the value of the variablefoo
, and sometimes the variablefoo
itself.我想,真正的答案(如果有的话)只能由原始语言设计者(John Ousterhout)给出。因此,其余的都可以进行猜测或(有根据的)猜测。 此处提供了有关 TCL 的一些历史记录,但快速阅读后发现没有直接答案那里。
我的看法是,这种方式更接近 (UNIX) shell 语言。 TCL 是在 Berkeley 构思的,可以说是一个强大的 UNIX(或 BSD)环境。
UNIX shell 在声明或分配变量时也不使用 $ 符号(或相应 shell 的等效符号),但在引用它时需要它:
即使是邪恶的 Windows CMD.EXE 处理器也使用类似的方法(尽管我猜这并不是 TCL 设计者的初衷;-)
另外,如果字符串值中现在有空格,“字符串值”(尽管 shell 是出了名的弱类型)通常不需要引号。
好吧,这不是为 TCL 设计师/创作者准备的;-)
编辑 我差点忘了:您实际上可以在 TCL 中执行以下操作:
这实际上会输出“某些内容”。第二行实际上将字符串“something”设置为变量“foo”的值,从而设置一个名为“bar”的变量并为其分配值“something”。
The real answer, if any, could only be given by the original language designers (John Ousterhout) I guess. So the rest is open to speculation or (educated) guesses. There is some history on TCL available here, but upon a quick reading there is no direct answer there.
My take would be that this way it is closer aligned to (UNIX) shell languages. TCL was conceived at Berkeley, arguably a strong UNIX (or BSD for that matter) environment.
UNIX shells also don't use the $ sign (or equivalent for the respective shell) when declaring or assigning variables, but require it when referencing it:
Even the unholy Windows CMD.EXE processor uses a comparable method (although I guess that was not what TCL designers had in mind ;-)
Also, "string values" (although shells are notoriously weak typed) don't generally require quotes if there are now spaces in the string value.
Well, it wasn't for the TCL designers/creators ;-)
EDIT I almost forgot: You could actually do the following in TCL:
This will actually output "something". The second line actually sets the string "something" to the value of the variable "foo", thus setting a variable named "bar" and assigning it the value "something".