【问题标题】:Why do Perl control statements require braces?为什么 Perl 控制语句需要大括号?
【发布时间】:2009-12-09 21:01:41
【问题描述】:

这可能看起来像最近提出的why Perl doesn't allow one-liners to be "unblocked," 的问题,但我发现该问题的答案并不令人满意,因为他们要么提到了the syntax documentation that says that braces are required,我认为这只是在乞求问题,要么忽略了这个问题,只是给了无牙套替代品。

为什么 Perl 需要为控制语句(如 iffor)使用大括号?换句话说,为什么 Perl 需要块而不是语句,就像其他一些流行语言允许的那样?

【问题讨论】:

    标签: perl syntax language-design


    【解决方案1】:

    一个原因可能是某些样式规定您应该始终使用带有控制结构的大括号,即使对于一个衬里也是如此,以避免以后破坏它们,例如:

    if (condition) 
       myObject.doSomething();
    else 
       myObject.doSomethingElse();
    

    然后有人在第一部分添加了更多内容:

    if (condition)
       myObject.doSomething();
       myObject.doSomethingMore(); // Syntax error next line
    else 
       myObject.doSomethingElse();
    

    或者更糟:

    if (condition)
       myObject.doSomething();
    else 
       myObject.doSomethingElse();
       myObject.doSomethingMore(); // Compiles, but not what you wanted.
    

    在 Perl 中,这类错误是不可能发生的,因为不使用带有控制结构的大括号总是语法错误。实际上,风格决定已在语言语法级别强制执行。

    这是否是真正的原因,只有拉里的小胡子知道。

    【讨论】:

    • “防止程序员错误”似乎不是一个非常“Perlish”的理由,至少在语法建立的时候不是。
    • @Rob:你在开玩笑吧? Larry 是一名 C 程序员。他可能比你或我想的更多次看到这个确切的错误。为什么他不决定用他设计的语言排除它,为什么时间与它有任何关系?
    • 在我看来,在 Perl 中有很多 other 容易出错的地方; this 是 Wall 选择解决的问题?至于时间,我觉得可维护性和初学者友好性比 20 年前更受重视,所以我有点难以相信这会包含在 那些 作为目标. (幸运的副作用,很好,但不是主要动机。)
    • @Rob:不过,“防止程序员错误”正是答案。许多看起来与 C 有点不同的东西来自 Larry 明确地避免了 C 编码中的这些问题。我没有你的参考,因为我主要是直接从拉里的嘴里听到的。
    • @Rob:我认为你的论点走错了方向,Perl 的现代流行观点正在影响你的判断。认为一个人会想出一种语言而不考虑防止错误是荒谬的。几十年后,Perl 中更明显的错误很容易犯:是一个不幸的副作用。
    【解决方案2】:

    一个原因可能是一些结构没有大括号会模棱两可:

    foreach (@l) do_something unless $condition;
    

    unless $condition 是适用于整个事物还是仅适用于 do_something 语句?

    当然,这可以通过优先规则或其他东西来解决, 但这将是另一种创建令人困惑的 Perl 代码的方法:-)

    【讨论】:

    • 那个特定的一半很容易 - 如果 $condition 独立于 do_something 那么它适用于 while 事物。反正你也不能说 PERL 是什么意思
    • 为自己说话。而且 perl 不是首字母缩写词。
    • @Oesor:实用提取和报告语言(或病理性不拘一格的垃圾列表)——它的拼写不像首字母缩略词,因为它看起来像那样喊......
    • 这不是一个首字母缩略词。这些反义词只是为了好玩。 Perl 这个名字本身来自于对 Pearl 的故意拼写偏差。
    【解决方案3】:

    无括号 if-else 子句的一个问题是它们会导致语法歧义:

    if (foo)
        if (bar)
           mumble;
        else
           tumble;
    

    鉴于上述情况,在什么条件下执行翻转?它可以被解释为在!foofoo && !bar 时发生。添加大括号可以消除歧义,而不会过多地污染源。然后您可以继续说,使用大括号总是一个好主意,所以让我们让语言需要它,并解决无休止的 C 争论,即是否应该使用它们。或者,当然,您可以通过完全摆脱大括号并使用缩进来指示嵌套来解决问题。两者都是使清晰、明确的代码成为自然的事情而不需要特别努力的方法。

    【讨论】:

    • 我似乎记得拉里在他的一次演讲中对同一问题的回答中指出了这个案例。
    【解决方案4】:

    在 Programming Perl(Larry Wall 合着)第 3 版,第 113 页中,复合语句是根据表达式和块定义的,而不是语句,块有大括号。

    请注意,与 C 和 Java 不同, [复合语句]定义在 BLOCKS 的条款,而不是陈述。 这意味着大括号是 要求——没有悬空语句 允许。

    我不知道这是否能回答你的问题,但在这种情况下,他似乎选择了一种简单的语言结构而不是例外。

    【讨论】:

    • 它也支持(尽管不能证明)他想排除 Drew Hall 和我在我们的回答中提到的错误的概念......
    • “--no dangling statements allowed”似乎是对 Brian 上面评论中提供的答案的肯定。
    【解决方案5】:

    也许与您关于(大概)Perl 5 及更早版本的问题没有直接关系,但是……

    在 Perl 6 中,控制结构不需要括号:

    if $x { say '$x is true' }
    
    for <foo bar baz> -> $s { say "[$s]" }
    

    如果大括号也是可选的,这将是非常模棱两可的。

    【讨论】:

    • Go 语言也有这个。
    【解决方案6】:

    难道不是Perl允许你跳过大括号,但是你必须写语句before条件?即

    #!/usr/bin/perl
    
    my $a = 1;
    
    if ($a == 1) {
        print "one\n";
    }
    
    # is equivalent to:
    
    print "one\n" if ($a == 1);
    

    【讨论】:

    • 有点惊讶没有其他人提出这个问题。是的,“语句修饰符”是 Perl 对无块条件的回答。它们允许人们将条件写在一行中,并将您正在做的事情放在首位,因为有时更重要的是强调正在做的事情而不是何时或多少次。
    • 除非这没有完全涵盖 C 风格无块 if 的功能,因为后缀条件不提供包含 else 的方法子句。
    • Schwern,我怀疑没有其他人提出这个问题,因为在我的问题中我说我对仅列出无手镯替代品的答案并不满意。 (为此,请转到另一个问题。)我想知道为什么常规控制语句不能无括号。如果语句修饰符真的在其他地方需要大括号的原因,那很好,但一些历史证据会很好。此外,这个答案实际上并没有这么说;它那个。
    【解决方案7】:

    "好的,所以通常情况下,你需要在块周围加上大括号,但如果块只有一个语句长,则不需要,当然,除非你的语句在某种方式上会受到优先规则的约束如果你省略了大括号,就不会像你想要的那样——在这种情况下,你也可以想象使用括号,但这会不一致,因为它毕竟是一个块——这当然取决于相应的优先级在任何情况下,你都不需要在右大括号之后加上分号——如果你结束一个 if 语句后跟一个 else 语句,那甚至是错误的——除非你绝对必须在最后加上一个分号C++ 中的头文件(或者是 C?)。"

    说真的,我很高兴代码中的每一个明确性和统一性。

    【讨论】:

    • 引号和斜体表明您在引用某人。请您引用您的出处好吗?
    • 来源是我邪恶的声音;)——我只是想让咆哮声脱颖而出。
    【解决方案8】:

    只是在这里猜测,但“未阻塞”循环/ifs/等。往往是在代码维护期间引入细微错误的地方,因为马虎的维护者可能会尝试在“循环内”添加另一行而没有意识到它真的在里面。

    当然,这是我们正在谈论的 Perl,所以可能任何依赖于可维护性的论点都是可疑的...... :)

    【讨论】:

    • 我假设反对票是针对最后一个小倒钩的? :) 不要误会我的意思,我其实很喜欢 Perl——但它复杂的语法会使代码“只写”。
    • 这也可能是因为你的答案是猜测,这不是答案(但我不能说,因为我不是它的作者:))
    • 投反对票可能是出于这两个原因中的一个或两个。 “只是猜测”部分对我来说是一个关闭。没有任何信息可以判断它是否正确。猜测没有错,但猜测有证据更好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-27
    • 2015-06-14
    • 2022-01-20
    • 1970-01-01
    • 2014-06-01
    • 2014-08-09
    • 2022-07-16
    相关资源
    最近更新 更多