Tcl 无大括号表达式中的空白

Tcl 无大括号表达式中的空白,tcl,Tcl,有趣的遭遇: set v "\{a b\}" expr $v eq \{a b\} expression命令按预期返回true。但以下情况也是正确的: set v "\{a b\}" expr $v eq \{a b\} 基本上,\{a和b\}之间的空格数被忽略 我知道TCL表达式应该支持参数 我知道没有人会认真地写这样的代码 我也能猜出发生了什么: 在脚本级解析中,空格仅用作单词分隔,一个或多个空格具有相同的效果 当涉及到命令expr时,它无法访问“原始”脚本,它只知道有两个单词

有趣的遭遇:

set v "\{a b\}"
expr $v eq \{a b\}
expression命令按预期返回true。但以下情况也是正确的:

set v "\{a b\}"
expr $v eq \{a      b\}
基本上,
\{a
b\}
之间的空格数被忽略

我知道TCL表达式应该支持参数

我知道没有人会认真地写这样的代码

我也能猜出发生了什么:

  • 在脚本级解析中,空格仅用作单词分隔,一个或多个空格具有相同的效果
  • 当涉及到命令
    expr
    时,它无法访问“原始”脚本,它只知道有两个单词,
    {a
    b}
    ,由一些空格分隔
  • 所以只使用了一个空格

  • 但是从编程语言TCL的角度来看,它是一个bug吗?

    TCL语法的第三条规则是

    命令的单词之间用空格分隔(除了换行符, 它们是命令分隔符)

    (命令名和参数字符串是单词。)

    expr
    文档中的第一条规定

    连接参数(在它们之间添加分隔符)

    因此,Tcl解析器将字符串
    expr$v eq\{a b\}
    分解为五个单词,丢弃它们之间的空白字符。然后,
    expr
    命令将其四个参数连接成一个字符串,每对参数之间有一个分隔符

    这与您在字符串上执行列表变异命令时看到的基本相同:

    % set a {a    b c}
    a    b c
    % lappend a d
    a b c d
    
    文件: ,

    不,这完全符合规定。将字符串拆分为列表时也会发生同样的情况。每次你想保留空白时,你都必须引用它。现在你明白了为什么人们总是被告知要用括号括住你的表达。在8.0 alphas期间(90年代中后期),曾有一项实验性举措,旨在减少像您这样的代码的“意外”,但用户社区拒绝了这一举措;让核心语言解析器对其规则完全没有例外被认为是一个更好的遵循原则。