我有一个Perl程序,它希望在一堆其他文件中运行Perl代码并获取每个文件中设置的所有变量。在正常情况下,这些其他文件将位于其自己的页面中,例如foo.pm内的package foo
。然后我只是use foo
,然后在%foo::
左右看看是什么定义的。我的挑战是其他文件不包含package
声明,因此无法修改。
Perl程序如何在未指定package
的其他Perl文件中运行代码并获取由它们设置的变量和值?
其他限制:
必须在Perl 5.10.1及更高版本中运行。可以使用5.10.1中的所有核心模块。
必须在Linux上工作。 (我目前正在使用Red Hat 6,但确切的分布可能会发生变化。)
我想尽量减少这个项目的依赖项数量。我愿意添加一个或两个额外的依赖项。
我将处理多个文件。其他文件必须不污染父级符号,也不污染其他文件的符号。目标是防止意外损坏;我可以放心地假设其他文件不是恶意的。其他文件不会尝试修改其他包,尽管它们可能是use
个模块本身。我愿意忍受运行其他文件代码导致的其他副作用。
(我重新写这个问题是为了更集中。前几个评论是针对以前的版本。)
答案 0 :(得分:2)
首先,强制性的:必须是做你想做的更好的方式。
如果您决定走这条路,您的原始方法很容易扩展。只需在一个新包中评估每个文件(使用do
),其中包含一个不太可能与程序中使用的任何其他包冲突的构造名称,然后检查该包的符号表。在此示例中,我将包命名为__Scratch__::__1
,__Scratch__::__2
等。
my $index = 0;
for my $file (@files) {
my $pkg = sprintf '__Scratch__::__%d', ++$index;
my $code = "package $pkg; do \$file; %$pkg\::";
my %symbol_table = eval $code;
# add error checking to taste...
print "Symbols defined after evaluating $file: ",
join(', ', keys %symbol_table), "\n";
}
答案 1 :(得分:0)
您说您无法修改文件,但是您可以修改文件的内存中内容吗?
例如,如果/path/to/somefile.pm
是您的非模块文件之一,则可以执行类似
open my $pm, "<", /path/to/somefile.pm or die;
my @lines = <$pm>;
eval(join("\n","package somefile;", @lines, "1;"));
# now you could do something like
somefile::afunction("hello");
现在你把它装在内存里就像一个合适的包。 (好的,不是正确的包。)