我可以内省正则表达式的插值吗?

cod*_*ons 8 regex rakudo string-interpolation raku

在下面的代码中,正则表达式$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?
Run Code Online (Sandbox Code Playgroud)

(我知道我可以通过手动解析访问相同的信息$r,发现所有的变量,然后走&g的callframes中变量的值。但是,这似乎是一个相当脆弱的黑客得到的信息是,正则表达式显然已经知道,至少在某种程度上。)

Jon*_*ton 14

我可以内省正则表达式的插值吗?

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

my $var = "foo";
my $rx = rx/$var/;
say "foobar" ~~ $rx;    # ?foo?
$var = "bar";
say "foobar" ~~ $rx;    # ?bar?
Run Code Online (Sandbox Code Playgroud)

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

它们gist的来源主要是出于实用原因(Test模块中更好的诊断输出可能是驱动力),但是它是通过Regex在编译时附加到对象的源代码字符串精确完成的。在运行时,它都是字节码,并且不涉及您看到的源字符串。

  • 不,闭包*引用*它们的外部作用域,并在其中读取(甚至写入)变量。考虑像 `sub counter($start is copy) { -> { $start++ } }; 这样的函数生成器 我的 $c = 计数器(40); 说 $c(); 说 $c(); 比如说 $c();`,它依赖于闭包语义,而不是关于值,而是关于引用。(这与 Java 模型相反,在 Java 模型中,闭包是用值创建的,然后值就不能被改变。) (3认同)