我正在阅读Donal Fellows关于为什么你应该支撑你的expr
的优秀解释。
这让我想知道为什么tcl编译器不自动支撑{}
的expr
?这种自动支撑在什么条件下会失效?
关于这个的一些随机想法…
- 该语言的优势之一是评估由少数统一应用的规则管理。将指向
expr
的参数自动括起来意味着必须在该命令的规则中有一个例外。 - 这也意味着解释器必须重写,因为它在确定处理哪个命令之前先计算参数。
expr
命令可以重命名或使用别名,这使得解释器很难判断何时使用自动括号。 - 这意味着如果有人想要对参数进行双重求值,或者想以不直接匹配表达式令牌的方式构造参数,他们将不得不绕过自动括号。
- 这意味着可能与许多旧代码不兼容。
让解释器充当"后座驾驶员"并不是真正的Tcl方式。
这让我想知道为什么tcl编译器不自动将
{}
和expr
括起来?
在8.0的一些alpha版本中确实是这样做的。它被删除了,因为更广泛的社区绝对讨厌它。核心Tcl语言——Tcl(n)手册页上的12条规则——被保持得非常小和简单,并且它被统一地应用于所有。
无特殊情况。是大多数Tcl程序员想要的。
如果我没记错的话,自动支撑是针对if
和while
特别考虑的。对于if
,这是因为在Tcl 7中省略对命令结果进行测试的大括号是一种特别常见的做法,因为它更快(表达式引擎慢得令人尴尬)。对于while
,这是因为省略大括号是一个常见的用户错误。
自动支撑在什么条件下会失效?
嗯,在这样的地方会很明显:
set a 1
set b 2
set op +
set c [expr $a$op$b]
现在,设置c
为3
。如果使用自动加括号,这将是一个语法错误(因为表达式语法不能处理一行中的三个变量)。提出了一个变通方法:
set c [eval expr $a$op$b]
但是坦率地说,让每个人都用大括号括他们的表达式,除非他们真的需要双替换(和运行时表达式编译),这被认为是更好的。
双替换几乎总是安全错误的指示,并且总是性能问题的指示;实际上,总有更好(更快、更安全)的方法来做这件事。用括号括住表达式。它更安全,更快捷,真的很容易做到:有什么不喜欢的呢?