regex - 我可以内省正则表达式的插值吗?
问题描述
在下面的代码中,Regex$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
,找到所有变量,然后步行&g
scallframe
来找到变量的值。但这似乎是一个相当脆弱的黑客获取正则表达式显然已经知道的信息,至少在某种程度上。)
解决方案
我可以内省正则表达式的插值吗?
不,因为它没有被插值,就像在闭包中{ say $a }
我们也不认为$a
被插值,而是说它被封闭了。正则表达式中的变量编译为该变量的查找,每次评估正则表达式时都会进行查找。这可以通过在正则表达式的评估之间更改变量的值来确认:
my $var = "foo";
my $rx = rx/$var/;
say "foobar" ~~ $rx; # 「foo」
$var = "bar";
say "foobar" ~~ $rx; # 「bar」
这里起作用的更大原则是,在 Raku 中,正则表达式不是由标准库中的某些正则表达式实现处理的字符串,而是已编译程序的一部分,并且与任何其他块或 thunk 具有相同的闭包语义。
他们gist
的来源主要是出于务实的原因(模块中更好的诊断输出可能是驱动力),但是它是通过在编译时Test
附加到对象的源代码字符串来完成的。Regex
到运行时,它都是字节码,不涉及您看到的源字符串。