我们在工作时使用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 =
”而不是获得真正的价值。
提前致谢。
答案 0 :(得分:8)
简短的回答是,用my
声明的变量不能在其词法范围之外访问。如果你不能将声明改为“我们的”(因为原始剧本的疯狂“编译”性质),你还没有运气。 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";
}
}
答案 1 :(得分:0)
如果您有想要的特定物品,这里是单线。.根据需要扩展。
perl -e'$ foo = eval(cat ./my.pl
。“ return \ $ some_my_var;”);打印“ $ foo”'