只是为了好玩,我编写了以下代码:
proc "bake a cake" {"number_of_people" {number_of_children}} {
set fmt "Take %d pounds of flour and %d bags of marshmallows."
puts [format $fmt "${number_of_people}" ${number_of_children}]
puts "Put them into the oven and hope for the best."
}
"bake a cake" 3 3
{bake a cake} 5 0
我发现很有趣的是过程名称可能包含空格。我认为,将其与本质上未使用的参数相结合,可以使 Tcl 程序看起来与口语自然语言非常相似,就像 Smalltalk 的 bakeACake forPeople: 3 andChildren: 3
所做的那样,只是没有奇怪的冒号扰乱了句子和不自然的词序。
为了进一步探索这个想法,我对过程的参数尝试了相同的模式,将每个 _
替换为一个简单的空格。 tclsh8.6 不喜欢它:
too many fields in argument specifier "number of people"
(creating proc "bake a cake")
invoked from within
"proc "bake a cake" {"number of people" {number of children}} {
set fmt "Take %d pounds of flour and %d bags of marshmallows."
puts [format $fmt "${n..."
(file "bake.tcl" line 1)
这引发了以下问题:
- 是否有令人信服的理由来解释为什么过程名称可以包含空格但参数名称不能?
- 这只是
proc
的实现细节吗? - 是否可以编写允许这种语法变体的
spaceproc
?
最佳答案
仔细阅读 proc
文档: arg 列表中的每个 args 本身就是一个列表,必须具有 1 或 2 个元素:强制参数名称和可选默认值。 “number of people”
元素过多。只需再戴一层大括号就可以得到你想要的东西:
% proc "bake a cake" {{"for people"} {"and children"}} {
puts "baking a cake for [set {for people}] people and [set {and children}] children"
}
% "bake a cake" 1 2
baking a cake for 1 people and 2 children
% "bake a cake"
wrong # args: should be "{bake a cake} {for people} {and children}"
我没有看到进行此实验的好处:尴尬的变量名称排除了 $
语法糖。
请注意,获得看起来像 Smalltalk 的代码并不困难
% proc bakeACake {forPeople: nPeople andChildren: nChildren} {
if {[set forPeople:] ne "forPeople:" || [set andChildren:] ne "andChildren:"} {
error {should be "bakeACake forPeople: nPeople andChildren: nChildren"}
}
puts "baking a cake for $nPeople people and $nChildren children"
}
% bakeACake
wrong # args: should be "bakeACake forPeople: nPeople andChildren: nChildren"
% bakeACake foo 1 bar 2
should be "bakeACake forPeople: nPeople andChildren: nChildren"
% bakeACake forPeople: 3 andChildren: 4
baking a cake for 3 people and 4 children
尽管与 Smalltalk 不同,您不能使用其他以“bakeACake”开头的命令(除非您深入研究“命名空间集合”)
关于arguments - 为什么 Tcl 允许过程名称带空格,但参数不允许带空格?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55463770/