这有效
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> $/;
}
这个
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> $/;
}
死于
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
我更喜欢第二个版本,因为我认为第一个版本在必须设置
token
时效率很低。 s 每次调用函数时。因此,如果这是真正的代码而不是挑战条目,我必须将 token (文件)设为全局。为什么会发生这种情况?
最佳答案
TL;DR 我喜欢 take 0 。有一个解决方法(参见 take 1 ),但我认为不值得。我不认为使用普通的 my
效率低下(参见 take 2 )。我认为在编译时应该拒绝将 state
与正则表达式/方法一起使用(参见 take 3 和 5 )或保持原样(参见 104 take 107919 3 )。除非你是一个愿意说服 jnthn 的编码天才,Rakudo 应该开始显着增加对 continuation 的暴露(参见 take 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> $/;
}
(正则表达式调用中对
&
的需求让我有点惊讶。1)为什么会发生这种情况? (取2)
为什么会发生什么?
I believe the first version is quite inefficient when it has to set up the tokens every time the function is called.
您所说的“相信”和“效率很低”以及“设置代币”是什么意思?我希望正则表达式代码只编译一次(如果每次都编译,我会感到震惊)但还没有进行分析以验证。
这让我想到了一系列问题:
您是否只关心每次调用
&opening-parens
函数时重新创建 3 个 lexpad 条目(test-string
等;更一般地说,正则表达式的数量)所花费的时间?您是否真的对运行原始代码进行了分析并发现了一个重大问题?
你有没有真正测量过,在实际项目中发现它是part of your "critical 3%"?
为什么会发生这种情况? (取3)
state
声明符对 sub
s 做了一个合理的事情——它产生一个编译时错误:state sub foo {} # Compile time error: "Cannot use 'state' with sub declaration"
state my sub foo {} # Compile time error: "Type 'my' is not declared"
但是使用一种方法(这是正则表达式的隐藏内容)它可以编译但没有任何用处:
state method foo {} # Compiles, but I failed to find a way to access `foo`
state regex bar {.} # Same
我查看了 Rakudo 的 GH 问题队列,但没有找到讨论类似上面最后两行代码的问题(与您的
token
案例基本相同)。也许人们没有注意到这一点,或者至少不觉得提交错误会有帮助?为什么会发生这种情况? (取4)
所以你会发布一个 SO 文档,说明
state regex
应该在编译时被拒绝或做一些有用的事情。 @Scimon++ 会记录另一种看待事物的方式。还有我一些。为什么会发生这种情况? (取5)
<Your Compiler Code Goes Here>
因为 Raku is our MMORPG 。如果您希望看到
state
声明符在与例程声明一起使用时做一些有用的事情(大概它应该会产生编译时错误,就像它目前对 sub
所做的那样,或者在 "scoped continuations" 的约束内做一些花哨的延续事情在 Raku 构建的顶部),那么鉴于 Rakudo 编译器主要是用 Raku 编写的,这项工作可能只是“轻而易举”的事情。有人故意使 state
上的 sub
成为编译时错误,而延续概念将是一个真正庞大的项目,所以我认为在接下来的几年中,如果有的话,适当的做法是在方法或规则也是一个编译时错误。或者,也许更合适的是,现在这已被 SO 所涵盖,并带有记录的替代方案(语法)和解决方法(采取 1),是时候进入下一个级别了……
脚注
1 见 my answer to Difference in ... regex scope。用
state
声明的正则表达式的行为似乎没有直接阅读我在该答案中引用的设计推测。至少我在那个答案中的以下叙述也是错误的......"
<bar>
is as explained above. It preferentially resolves to an early bound lexical (my
/our
) routine/rule named&bar
.
...因为在这个答案的 take 1 代码中,正则表达式调用必须以
state
为前缀才能工作。也许他们工作完全是偶然的。
关于regex - 结合状态和 token 抛出。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59615980/