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

从不在包中的其他Perl程序中读取变量,perl,Perl,我有一个Perl程序,它希望在一堆其他文件中运行Perl代码,并获取每个文件中设置的所有变量。在正常情况下,这些其他文件将位于它们自己的页面中,例如foo.pm内的package foo。然后我只需使用foo,然后在%foo::中浏览一下,看看定义了什么。我的挑战是,其他文件不包含包声明,因此无法修改 Perl程序如何在没有指定包的其他Perl文件中运行代码,并获取它们设置的变量和值 其他限制: 必须在Perl 5.10.1及更高版本中工作。5.10.1中的所有核心模块均可用 必须在Linux

我有一个Perl程序,它希望在一堆其他文件中运行Perl代码,并获取每个文件中设置的所有变量。在正常情况下,这些其他文件将位于它们自己的页面中,例如foo.pm内的
package foo
。然后我只需使用foo
,然后在
%foo::
中浏览一下,看看定义了什么。我的挑战是,其他文件不包含
声明,因此无法修改

Perl程序如何在没有指定
包的其他Perl文件中运行代码,并获取它们设置的变量和值

其他限制:

  • 必须在Perl 5.10.1及更高版本中工作。5.10.1中的所有核心模块均可用

  • 必须在Linux上工作。(我目前正在使用Red Hat 6,但确切的分布可能会发生变化。)

  • 我想尽量减少这个项目的依赖数量。我愿意添加一个或两个额外的依赖项

  • 我将处理多个文件。其他文件不能污染父文件的符号,也不能污染其他文件的符号。目标是防止意外损坏;我可以放心地假设其他文件不是恶意的。其他文件不会尝试修改其他包,尽管它们可能使用模块本身。我愿意忍受运行另一个文件的代码所带来的其他副作用


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

你说你不能修改文件,但是你能修改文件的内存内容吗

例如,如果
/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");

打开我的$pm,”首先,必须做的是:必须有更好的方法来做你想做的事

如果你决定走这条路,你最初的方法很容易扩展。只需评估每个文件(使用
do
)在具有构造名称的新包内,该名称不太可能与程序中使用的任何其他包发生冲突,然后检查该包的符号表。在本例中,我将这些包命名为
\uuuu Scratch\uuuu::\uuu 1
\uu Scratch\uuu::\uuu 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";
}

过去,所有Perl程序员都编写模板和ORM库。现在,这很可能是在重新发明轮子。从谁将编辑/管理模板数据开始,然后反向工作,以确定技术以及这些人将如何访问足够详细的内容来完成他们的工作。您最好选择其中一个更复杂的模板库,然后使用数据库管理数据(示例中为
$author
$title
)。我当然写了我自己的模板引擎。:-)后来我变得聪明起来,转而使用模板工具包。我很有可能会把这件事交给一个对Perl或我使用的任何东西都不熟练的人,但他们希望扩展它、修复它,甚至完全替换它。这个人可能除了一个基准Linux系统之外什么都没有.因此,移动部件越少越好。从好处看,用户都是程序员,因此我可以处理更多(例如Perl输入文件)。我的真正目标是:不要让下一个家伙像我得到它时那样生气。:-)不修改原始文件的限制仅限于原始位置中的原始文件。我可以修改内存中的其他文件,并将修改后的版本保存到其他位置。我每次运行时都需要继续使用原始版本。