gpt4 book ai didi

perl - 打印出匿名子程序的代码

转载 作者:行者123 更新时间:2023-12-02 14:01:59 25 4
gpt4 key购买 nike

我目前正在一个非常复杂的 Perl 架构中工作,我想创建一些调试工具。由于很多行为都涉及匿名子例程,因此我想分析其中一些行为,而我所要做的就是对子例程的引用。

简而言之,有没有办法打印子例程引用的代码(因为 Perl 被解释,它可能仍然可用?)?

最佳答案

核心模块B::Deparse提供此功能。

use B::Deparse ();

my $deparse = B::Deparse->new;

my $code = sub {print "hello, world!"};

print 'sub ', $deparse->coderef2text($code), "\n";

打印:

sub {
print 'hello, world!';
}

当使用B::Deparse时,重要的是要记住它返回的是操作码编译树的反编译版本,而不是原始源文本。这意味着优化器可以折叠和重写常量、算术表达式和其他结构。

难题的另一部分是处理封闭的词法变量。如果您正在使用的子例程访问任何外部词法,它们将不会出现在 deparse 的输出中,并将导致重新编译失败。您可以使用 PadWalker 中的 lined_overset_lined_over 函数来解决此问题。模块。

use PadWalker qw/closed_over set_closed_over/;

my $closure = do {
my $counter = 0;
sub {$counter++}
};

print $closure->(), ' ' for 1..3; # 0 1 2
print "\n";

my $pad = closed_over $closure; # hash of lexicals

# create dummy lexicals for compilation
my $copy = eval 'my ('.join(','=> keys %$pad).');'.
'sub '.$deparse->coderef2text($closure);

set_closed_over $copy, $pad; # replace dummy lexicals with real ones

print $copy->(), ' ' for 1..3; # 3 4 5

最后,如果你想找出子程序的真正源代码在哪里,可以使用核心 B模块:

use B ();
my $meta = B::svref_2object($closure);

print "$closure at ".$meta->FILE.' line '.$meta->GV->LINE."\n";

打印如下内容:

CODE(0x28dcffc) at filename.pl line 21

关于perl - 打印出匿名子程序的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5589397/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com