【问题标题】:Can I introspect a Regex's interpolated value?我可以内省正则表达式的插值吗?
【发布时间】:2021-04-20 13:45:07
【问题描述】:

在下面的代码中,正则表达式 $r 清楚地“知道”它包含文本 bar——这就是它能够与 Str bar 匹配的方式。但是.gist.raku 报告$r 包含变量$foo,而没有说明$foo 包含什么值。有没有办法让$r 告诉我它的计算值?

sub f {
    my $foo = 'bar';
    g(rx/$foo/);
}

sub g($r) {
    say $r.gist;
    say 'bar' ~~ rx/$r/;
}

f # OUTPUT:  rx/$foo/
  #          「bar」

(我知道我可以通过手动解析$r,查找所有变量,然后遍历&gcallframes 来查找变量的值来访问相同的信息。但这似乎相当获取 Regex 显然已经知道的信息,至少在某种程度上是这样的。)

【问题讨论】:

    标签: regex raku string-interpolation rakudo


    【解决方案1】:

    我可以内省 Regex 的插值吗?

    不,因为它没有被 插值,就像在 { say $a } 闭包中一样,我们也不会将 $a 视为被插值,而是说它被封闭了。正则表达式中的变量编译为该变量的查找,每次评估正则表达式时都会进行查找。这可以通过在正则表达式的评估之间更改变量的值来确认:

    my $var = "foo";
    my $rx = rx/$var/;
    say "foobar" ~~ $rx;    # 「foo」
    $var = "bar";
    say "foobar" ~~ $rx;    # 「bar」
    

    这里起作用的更大原则是,在 Raku 中,正则表达式不是由标准库中的某些正则表达式实现处理的字符串,而是已编译程序的一部分,并且与任何其他块或任何其他块具有相同的闭包语义。呜呜呜。

    他们gist 到他们的来源主要是出于务实的原因(Test 模块中更好的诊断输出可能是驱动力),但是它正是通过附加到@987654326 的源代码字符串来完成的@object 在编译时。到运行时,都是字节码,不涉及你看到的源字符串。

    【讨论】:

    • 谢谢。这完全回答了我关于正则表达式的问题,但提出了关于 Raku 中的词法作用域如何工作的新问题。我本来预计{say $var } 在定义它时会关闭$a,但看起来它在定义它的范围结束时关闭了$a 的最终值。对吗?
    • 不,闭包引用它们的外部范围,并在其中读取(甚至写入)变量。考虑像@​​987654330@ 这样的函数生成器,它依赖于闭包语义,而不是关于值,而是引用。 (这与 Java 模型形成对比,在 Java 模型中,闭包是使用值创建的,然后可能不会发生变异。)
    • 啊哈,谢谢;这消除了我的困惑。绑定到只读引用的语义与复制值的语义非常接近,我能够将它们混合很长一段时间而不会被严重绊倒。但是,一旦您指出了差异,一切就都到位了。 :)
    猜你喜欢
    • 1970-01-01
    • 2010-09-29
    • 2015-08-26
    • 2015-03-08
    • 1970-01-01
    • 2012-08-28
    • 1970-01-01
    • 2013-05-23
    相关资源
    最近更新 更多