使用Tcl开关命令时,必须有额外的评估级别。这是repl上的一个示例会话,以显示我的意思:
$ tclsh
% regexp {^\s*foo} " foo"
1
% regexp {^\\s*foo} " foo"
0
% switch -regexp " foo" {^\\s*foo {puts "match"}}
match
% switch -regexp " foo" {{^\s*foo} {puts "match"}}
match
...在第一个“switch”版本中需要添加额外的反斜杠。这在Windows上的8.5.0和8.6.0之间是一致的。有人能指出我的手册部分,其中描述了这种类似的额外级别的不引用的情况吗?我的第一个想法是,第一个“切换”版本中的大括号会保护反斜杠,但“切换”本身必须对模式应用额外的反斜杠限制。除非我误解别的东西的细微差别。
修改 ......嗯......就像约翰内斯库恩所说的,下面的反斜杠替换显然取决于动态的使用环境,而不是创造的词汇背景......
% set t {\s*foo}
\s*foo
% proc test_s x {set x}
% test_s $t
\s*foo
% proc test_l x {lindex $x 0}
% test_l $t
s*foo
% puts $t
^\s*foo
......这似乎是一个非常有趣的设计选择。
答案 0 :(得分:2)
您在此处描述的问题很容易解决:
switch
和regexp
之间的区别在于切换实际上是一个列表
因此,如果我们使用
{^\s*foo {puts "match"}}
的第一个元素
% puts [lindex {^\s*foo {puts "match"}} 0]
^s*foo
它会导致我们不想要的东西。
列表构建是little bit complex,如果您不确定,请使用交互式Tcl shell,使用list
为您构建一个。
编辑:确实,这是一个有趣的设计选择,但这适用于Tcl中的所有内容。例如,expr
使用为算术表达式设计的小语言。命令取决于它应该如何处理它的论点。甚至像if
,for
,while
这样的语言结构也只是将其中一个参数视为表达式而其他参数作为脚本处理的命令。这种设计可以创建新的控制结构,比如sqlite的eval,它采用SQL语句和它应该为每个结果评估的脚本。