我们在工作时使用Perl脚本来执行维护.我需要修改它来处理更多任务.问题是脚本被编译并且源很久以前就丢失了.
我尝试使用B :: Deparse来重新创建文件,但Deparse并不完美,输出被破坏(非常大~5000行的去除代码).
读完解码后的代码后,我发现需要修改一个函数.编译后的脚本加载了一个纯文本脚本模块,因此我更改了模块以覆盖该函数并执行我需要它执行的任务.现在的问题是我无法访问主脚本“我的”变量.
这是一个例子:
# main.pl my $a = 1; sub call_me { print "unmodified"; } use MOD; call_me; MOD.pm package MOD; main::{'call_me'} = sub { print "\$main::a = $main::a\n"; }
结果是:“$main :: a =”而不是获得真正的价值.
提前致谢.
解决方法
简短的回答是,用我声明的变量不能在其词法范围之外访问.如果你不能将声明改为“我们的”(因为原始剧本的疯狂“编译”性质),你还没有运气. Perl几乎总是提供绕过这些类型的东西的方法.
在这种情况下,您可以安装PadWalker模块并执行类似的操作(这是您最初发布的代码的调整版本):
main.pl脚本:
my $a = 1; sub call_me { print "unmodified: $a"; } use MOD; call_me;
然后你的模块:
package MOD; # closed_over($code_ref) returns a hash ref keyed on variable # name(including sigil) with values as references to the value # of those variables use PadWalker qw(closed_over); { # grab a reference to the original sub my $orig = \&main::call_me; # no need to use the symbol table,a glob reference is fine # but you can't use sub main::call_me { ... } either *main::call_me = sub { my $a = closed_over($orig)->{'$a'}; print "\$main::a = $$a\n"; } }