结合状态和令牌抛出。为什么?

Hol*_*lli 7 regex raku

这有效

sub test-string( $string )
{
    my token opening-brace { \( };
    my token closing-brace { \) };
    my token balanced-braces { 
        ( <opening-brace>+ ) <closing-brace> ** { $0.chars } 
    };

    so $string ~~ /^ <balanced-braces> $/;
}
Run Code Online (Sandbox Code Playgroud)

这个

sub test-string( $string )
{
    state token opening-brace { \( };
    state token closing-brace { \) };
    state token balanced-braces { 
        ( <opening-brace>+ ) <closing-brace> ** { $0.chars } 
    };

    so $string ~~ /^ <balanced-braces> $/;
}    
Run Code Online (Sandbox Code Playgroud)

死于

No such method 'opening-brace' for invocant of type 'Match'
  in regex balanced-braces at ch-2.p6 line 13
  in sub test-string at ch-2.p6 line 17
  in block <unit> at ch-2.p6 line 23
Run Code Online (Sandbox Code Playgroud)

我更喜欢第二个版本,因为我相信第一个版本在token每次调用函数时都必须设置s时效率很低。因此,如果这是真正的代码而不是挑战条目,我必须将令牌(文件)设为全局。

为什么会发生这种情况?

rai*_*iph 6

TL;DR我喜欢0。有一种解决方法(参见第1 条),但我认为不值得。我不认为它是低效的my(见 take 2)。我认为state在编译时应该拒绝使用正则表达式/方法(参见 take 35)或保持原样(参见 take 4)。除非你是一个编码天才,愿意说服 jnthn Rakudo 应该开始显着增加对延续的暴露(参见第5 部分)。

为什么会发生这种情况?(取1)

如果你这样写,“这个”就不会:

sub test-string( $string )
{
    state &opening-brace = token { \( }
    state &closing-brace = token { \) }
    state &balanced-braces = token { 
        ( <&opening-brace>+ ) <&closing-brace> ** { $0.chars } 
    }

    so $string ~~ /^ <&balanced-braces> $/;
}   
Run Code Online (Sandbox Code Playgroud)

&在正则表达式调用中的需要让我有点惊讶。1

为什么会发生这种情况?(取2)

为什么什么发生?

我相信第一个版本在每次调用函数时都必须设置令牌时效率很低。

您所说的“相信”和“效率很低”以及“设置代币”是什么意思?我希望正则表达式代码只编译一次(如果每次都编译,我会感到震惊)但还没有进行分析以进行验证。

这让我想到了一系列问题:

您是否只关心&opening-parens每次test-string调用函数时重新创建 3 个 lexpad 条目(等等;更一般地说,正则表达式的数量)所花费的时间?

您是否真的对运行原始代码进行了分析并发现了一个重大问题?

您是否真的对此进行了衡量并发现它是实际项目中“关键 3%”的一部分?

为什么会发生这种情况?(取3)

state声明符做一件合理的事与sub秒-它会产生一个编译时错误:

state sub foo {}    # Compile time error: "Cannot use 'state' with sub declaration"
state my sub foo {} # Compile time error: "Type 'my' is not declared"
Run Code Online (Sandbox Code Playgroud)

但是使用一种方法(这是正则表达式的隐藏内容)它可以编译但没有任何用处:

state method foo {} # Compiles, but I failed to find a way to access `foo`
state regex bar {.}  # Same
Run Code Online (Sandbox Code Playgroud)

我查看了 Rakudo 的 GH 问题队列,但没有找到讨论类似上面最后两行代码的问题(与您的token情况基本相同)。也许人们没有注意到这一点,或者至少不觉得提交错误会有帮助?

为什么会发生这种情况?(取4)

所以你会发布一个 SO 文档,state regex应该在编译时被拒绝或做一些有用的事情。@Scimon++ 会记录另一种看待事物的方式。还有我一些。

为什么会发生这种情况?(取5)

<Your Compiler Code Goes Here>
Run Code Online (Sandbox Code Playgroud)

因为乐是我们的 MMORPG。如果您希望看到state声明符在与例程声明一起使用时做一些有用的事情(大概它应该会产生编译时错误,就像它目前对 a 所做的那样sub,或者在“作用域延续“在 Raku 构建的顶部),那么鉴于 Rakudo 编译器主要是用 Raku 编写的,那么这项工作似乎只是“轻而易举”的事情。有人故意犯statesub一个编译时错误,而延续的概念将是一个真正庞大的项目,所以我认为在接下来的几年里,适当的事情,如果有的话,是state在一个方法或规则上也编译时错误。

或者,也许更合适的是,现在这已被 SO 所涵盖,并带有记录的替代方案(语法)和解决方法(采取 1),是时候进入下一个级别了……

脚注

1请参阅我对...正则表达式范围中的差异的回答。声明为 with 的正则表达式的行为state似乎没有直接阅读我在该答案中引用的设计推测。至少我在那个答案中的以下叙述也是错误的......

"<bar>如上所述。它优先解析为名为的早期绑定词法 ( my/ our) 例程/规则&bar

...因为在这个答案的 take 1 代码中,正则表达式调用必须以 an&为前缀才能工作。也许他们工作完全是偶然的。