regex - 在 Regex 上调用 Bool 无法按文档工作

标签 regex oop raku

根据 the documentation , Bool Regex的方法类(class)...

Matches against the caller's $_ variable, and returns True for a match or False for no match.



然而,在这个例子中
$_ = "3";
my regex decimal { \d };
say &decimal.Bool;

返回 False .另外,looking at the source ,它说的有点道理,因为它将匹配 $!topic实例变量。然而,不清楚这个变量是否会有效地对应于 $_,上面的例子似乎是这样说的。知道实际发生了什么吗?

最佳答案

简短的回答:文档对于 6.c 来说有点准确,但是确切的语义根本不像“调用者”那么简单(事实上,包含非常奇怪的错误的风险)。改进后的行为是:

  • 匿名正则表达式由类似 /.../ 的形式构成和 rx:i/.../将捕获 $_$/在代码中到达它们时(填充问题中提到的 $!topic 变量)。
  • Boolsink将导致与捕获的匹配 $_ ,并将存储结果 Match反对那个 $/ ,只要它是可写的。

  • 由于此行为仅适用于匿名正则表达式,因此您需要编写:
    $_ = "3";
    my regex decimal { \d };
    say /<&decimal>/.Bool;
    

    这是长答案。 Bool的目标-causes-matching 行为首先是为了让这样的事情起作用:
    for $file-handle.lines {
        .say if /^ \d+ ':'/;
    }
    

    在这里,for循环填充主题变量 $_ ,以及 if提供一个 bool 上下文。原来的设计是.Bool会看$_来电者的。但是,这存在许多问题。考虑:
    for $file-handle.lines {
        .say if not /^ \d+ ':'/;
    }
    

    在这种情况下,not.Bool的来电者在 Regex .然而,not也会有自己的$_ , 就像在任何子程序中一样 - 将被初始化为 Any .因此理论上,匹配将不起作用。除此之外,因为实际实现的是遍历调用者,直到找到带有 $_ 的调用者为止。包含一个定义的值!这听起来很糟糕。考虑这样一个案例:
    sub foo() {
        $_ = some-call-that-might-return-an-undefiend-value();
        if /(\d+)/ {
            # do stuff
        }
    }
    $_ = 'abc123';
    foo();
    

    foo 内部调用的情况下将返回一个 undefiend 值 - 也许是出乎意料的 - 匹配会继续沿着调用者链走,而是找到了 $_ 的值。在 foo 的来电者中.事实上,我们可以在调用堆栈中深入很多层! (旁白:是的,这也意味着 $/ 也需要更新结果的复杂性!)

    之前的行为还要求$_具有动态范围 - 即可供调用者查找。但是,具有动态范围的变量会阻止大量分析(编译器和程序员的分析)以及优化。许多成语使用 $_ ,这似乎是不可取的(没有人希望看到 Perl 6 性能指南建议“不要在热代码中使用 with foo() { .bar },而是使用 with foo() -> $x { $x.bar }”)。因此,6.d已更改 $_成为一个常规的词法变量。

    那个 6.d $_范围变化对现实世界的影响相当小,但它确实导致了 .Bool 的语义。和 .sinkRegex需要检查,因为它们是依赖 $_ 的一个经常使用的东西。动态。这反过来揭示了我刚刚描述的“第一个定义的 $_”行为——在这一点上,动态范围的使用开始看起来更像是危险而不是好处!

    新语义意味着编写匿名正则表达式的程序员可以依赖它匹配 $_并更新 $/在他们编写正则表达式的范围内可见 - 这似乎更容易解释,并且 - 在这种情况下,他们最终会得到 $_这没有定义 - 不那么令人惊讶!

    关于regex - 在 Regex 上调用 Bool 无法按文档工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56815925/

    相关文章:

    php - PDO::FETCH_ASSOC 返回 false

    C++:矩阵计算器的高级类模型

    C# 检查一个类是否是 X,或者是从 X 继承的

    asynchronous - 如何杀死一个线程,停止 Raku 中的 promise 执行

    sequence - 为什么 Perl 6 序列 'A' ... 'AA' 只有一个元素?

    raku - 在 Raku 中一步使用变量并为其分配表达式

    java - 正则表达式限制重复类子字符

    java - 正则表达式:捕获一个或多个组(如果存在)(Java)

    c# - 在 C# 中使用 Regex 比较两个不同的文件夹

    python - python问题中字符串的翻译器