为什么这个 Perl 6 提要运算符是 "bogus statement"?

Why is this Perl 6 feed operator a "bogus statement"?

我从 Day 10 – Feed operators of the Perl 6 2010 Advent Calendar 中获取了这个示例,对 .uc 进行了轻微更改,因为 .ucfirst 不再存在:

my @rakudo-people = <scott patrick carl moritz jonathan jerry stephen>;
@rakudo-people
    ==> grep { /at/ } ==> map { .uc } ==> my @who-it's-at;
say ~@who-it's-at;

我写的略有不同,增加了一些空格:

my @rakudo-people = <scott patrick carl moritz jonathan jerry stephen>;
@rakudo-people
    ==> grep { /at/ }
    ==> map { .uc } ==> my @who-it's-at;
say ~@who-it's-at;

现在是 "bogus statement":

===SORRY!=== Error while compiling ...
Bogus statement
------>         ==> grep { /at/ }⏏<EOL>
expecting any of:
    postfix
    prefix
    statement end
    term

这不是这个例子的问题。当前文档中的一些示例可以表现出相同的行为。

如果我在有问题的行末尾添加一个 unspace,它会再次起作用:

my @rakudo-people = <scott patrick carl moritz jonathan jerry stephen>;
@rakudo-people
    ==> grep { /at/ } \
    ==> map { .uc } ==> my @who-it's-at;
say ~@who-it's-at;

奇怪的是,该行末尾的注释不起作用。我原以为它会吃掉令人讨厌的空格。

feed operator 说:

In the case of routines/methods that take a single argument or where the first argument is a block, it's often required that you call with parentheses

有效:

my @rakudo-people = <scott patrick carl moritz jonathan jerry stephen>;
@rakudo-people
    ==> grep( { /at/ } )
    ==> map { .uc } ==> my @who-it's-at;
say ~@who-it's-at;

但为什么第一种形式不是问题呢?空格在这里做什么? "often required"包括哪些情况?

来自 Separating Statements 上的 Perl 6 文档:

A closing curly brace followed by a newline character implies a statement separator

换句话说,每当块的 右大括号 是一行中的最后一个东西(不包括空格和注释)时,解析器会在其后隐式插入一个分号.

这允许我们在 }:

之后不带分号地写出如下内容
my @foo = @bar.map: {
    ...
}

那里的分号会很难看,如果您首先将循环编写为 for @bar { ... } 然后决定将其变成 map 并使用这样的赋值,添加尾随分号将是烦人且容易忘记。所以在大多数情况下,这种在行尾块后自动终止语句是有帮助的。

但是,进料操作员向块中进料是一种(可能是唯一的)绊倒人的情况。

为了防止它发生,请在块后插入 \ (a.k.a. unspace),正如您已经注意到的那样。 unspace 使包含换行符的空格对解析器不可见,因此不会应用上述基于换行符的解析器规则。