给定一个 CODE ref,是否可以:
- 访问该 CODE ref 的解析树
- 通过指定 CODE ref 的解析树来创建一个新的 CODE ref,该解析树可以包含1返回的解析树的元素
通常我们通过指定源代码在 perl 中创建子例程,然后将其解析并转换为解析树。
我想编写一个 perl 函数,它可以通过指定其解析树来创建子例程,并且该解析树可以从其他子例程的另一个解析树派生。
可能的?
我不知道您问题的完整答案,但我知道 Data::Dumper 可以解析代码引用。查看它的文档,我发现它用于B::Deparse
完成繁重的工作(B::
模块是与编译器交互的模块)。不幸的是,这似乎只会导致 coderef 的文本表示。
相反,我Op
在 metacpan 上搜索并获得了更多有趣的可能性。由于我现在在最深的 Perl 魔法方面还不够深入,所以我将留给您查看这些结果。也许有些东西会有用。
这与操作码无关,但它确实将相同的两个变量包含在三个不同的闭包中。这些变量包含在子例程中,让人想起类 get/set 例程,然后这些关闭的变量通过它们的访问例程由其他闭包共享。
这是对评论的回应:我确信有必要访问解析树中的底层节点,以便我可以创建在相同变量上关闭的新闭包。
use strict;
use warnings;
use v5.14;
# create closed vars
my $v1 = access_closure(6);
my $v2 = access_closure(42);
# play with them
say "v1 ", &$v1;
say "v2 ", &$v2;
say "v1 ", &$v1(5);
say "v2 ", &$v2(43);
say "v1 ", &$v1;
say "v2 ", &$v2;
# create silly closures that use them
my $test1 = test_closure(2);
my $test2 = test_closure(17);
my $test3 = test_closure(50);
# play with those
&$test1;
&$test2;
&$test3;
# create the get/set routine for a closed var
sub access_closure {
my $val = shift;
return sub {
$val = shift if @_;
return $val;
}
}
# create a silly closure that encloses a control var and uses the two other vars
sub test_closure {
my $val = shift;
return sub {
say "\nval is $val";
printf "v1 is %2d, v2 is %2d\n",
&$v1, &$v2;
if (&$v1 < $val) {
say "Increment v1";
&$v1(&$v1+1);
}
if (&$v2 > $val) {
say "Decrement v2";
&$v2(&$v2-1);
}
printf "v1 is %2d, v2 is %2d\n",
&$v1, &$v2;
}
}