2014-01-13 26 views
1

我有一个Perl程序想要在一堆其他文件中运行Perl代码并获取每个文件中设置的所有变量。在正常情况下,这些其他文件将位于它们自己的页面中,例如,foo.pm中的package foo。然后我只是use foo,然后在%foo::周围看看是什么定义的。我的挑战是其他文件不包含package声明,并且无法修改。从其他不在包中的Perl程序中读取变量

Perl程序如何在其他未指定package的Perl文件中运行代码并获取由它们设置的变量和值?

附加限制:

  • 必须在Perl 5.10.1及更高版本。从5.10.1开始的所有核心模块都可用。

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

  • 我想尽量减少此项目所依赖的数量。我打算添加一个或两个额外的依赖项。

  • 我将处理多个文件。有必要让其他文件不会污染父母的符号,也不会污染其他文件的符号。目标是防止意外损坏;我可以安全地假设其他文件不是恶意的。其他文件不会尝试修改其他软件包,尽管它们本身可能是use模块。我愿意忍受由运行其他文件代码造成的其他副作用。

(我重新写了这个问题更集中,第一几点意见正在解决以前的版本。)

+1

它曾经是*所有* Perl程序员写的模板和ORM库。现在,这很可能重新发明轮子。首先由谁来编辑/管理模板数据,然后向后确定技术以及这些人员如何以足够的细节访问内容以完成他们的工作。使用更复杂的模板库之一,然后使用数据库作为托管数据(在您的示例中为'$ author'和'$ title'),您可能会更好。 –

+0

我当然写了我自己的模板引擎。 :-)后来我变得聪明起来,转移到Template Toolkit。 我很有可能会把它交给一个不熟练的Perl或其他我使用的人,但是会期望它能够扩展,修复它,甚至完全替代它。除了基本的Linux系统之外,这个人可能没有任何东西。所以移动部件越少越好。好的,用户都是程序员,所以我可以逃脱更多的(例如Perl输入文件)。 我的真正目标:不要让下一个人像我当时那样生气。 :-) –

+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"; 
} 
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"); 

现在你已经得到它加载到内存中像一个真正的包。 (好吧,不是正确包。)

相关问题