从其他不在包中的Perl程序中读取变量

时间:2014-01-13 07:03:33

标签: perl

我有一个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个模块本身。我愿意忍受运行其他文件代码导致的其他副作用。

(我重新写这个问题是为了更集中。前几个评论是针对以前的版本。)

2 个答案:

答案 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");

现在你把它装在内存里就像一个合适的包。 (好的,不是正确的包。)