这有效
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时效率很低。因此,如果这是真正的代码而不是挑战条目,我必须将令牌(文件)设为全局。
为什么会发生这种情况?
TL;DR我喜欢取0。有一种解决方法(参见第1 条),但我认为不值得。我不认为它是低效的my
(见 take 2)。我认为state
在编译时应该拒绝使用正则表达式/方法(参见 take 3和5)或保持原样(参见 take 4)。除非你是一个编码天才,愿意说服 jnthn Rakudo 应该开始显着增加对延续的暴露(参见第5 部分)。
如果你这样写,“这个”就不会:
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)
为什么什么发生?
我相信第一个版本在每次调用函数时都必须设置令牌时效率很低。
您所说的“相信”和“效率很低”以及“设置代币”是什么意思?我希望正则表达式代码只编译一次(如果每次都编译,我会感到震惊)但还没有进行分析以进行验证。
这让我想到了一系列问题:
您是否只关心&opening-parens
每次test-string
调用函数时重新创建 3 个 lexpad 条目(等等;更一般地说,正则表达式的数量)所花费的时间?
您是否真的对运行原始代码进行了分析并发现了一个重大问题?
您是否真的对此进行了衡量并发现它是实际项目中“关键 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
情况基本相同)。也许人们没有注意到这一点,或者至少不觉得提交错误会有帮助?
所以你会发布一个 SO 文档,state regex
应该在编译时被拒绝或做一些有用的事情。@Scimon++ 会记录另一种看待事物的方式。还有我一些。
<Your Compiler Code Goes Here>
Run Code Online (Sandbox Code Playgroud)
因为乐是我们的 MMORPG。如果您希望看到state
声明符在与例程声明一起使用时做一些有用的事情(大概它应该会产生编译时错误,就像它目前对 a 所做的那样sub
,或者在“作用域延续“在 Raku 构建的顶部),那么鉴于 Rakudo 编译器主要是用 Raku 编写的,那么这项工作似乎只是“轻而易举”的事情。有人故意犯state
了sub
一个编译时错误,而延续的概念将是一个真正庞大的项目,所以我认为在接下来的几年里,适当的事情,如果有的话,是state
在一个方法或规则上也编译时错误。
或者,也许更合适的是,现在这已被 SO 所涵盖,并带有记录的替代方案(语法)和解决方法(采取 1),是时候进入下一个级别了……
1请参阅我对...正则表达式范围中的差异的回答。声明为 with 的正则表达式的行为state
似乎没有直接阅读我在该答案中引用的设计推测。至少我在那个答案中的以下叙述也是错误的......
"
<bar>
如上所述。它优先解析为名为的早期绑定词法 (my
/our
) 例程/规则&bar
。
...因为在这个答案的 take 1 代码中,正则表达式调用必须以 an&
为前缀才能工作。也许他们工作完全是偶然的。