Perl动态重复加载代码的正确方法是什么?

时间:2014-11-26 23:54:52

标签: perl

我有一个perl脚本需要按顺序执行一些已知的运行时数量的子脚本,但如果子脚本共享主程序的状态信息(子脚本)将会很有帮助/方便但是,不需要更改状态信息。主脚本将使用ZIP文件目录的名称进行调用,每个ZIP文件中都会包含一个perl模块/库/脚本,可能名称相同,但不一定如此。< / p>

我想过尝试的一些事情:

  1. 让每个子脚本提供一个RunMe.pm模块,该模块将被加载,使用,然后卸载(通过操纵%INC - ugh)
  2. 为每个子脚本分叉requireuse RunMe.pm,做任何事情,然后退出
  3. 改为编写一个perl库,并doeval库(尽管我认为使用do仍然需要操作%INC
  4. 在Java中我会有一个类实现一个接口并有一个工厂来创建所有这些,虽然我不知道在编译时实现类的名称,所以我求助于Class.forName()

    所有这些都是丑陋的一面,并引导我完全重新考虑设计理念,这可能是正确答案。

2 个答案:

答案 0 :(得分:1)

zip文件真的有必要吗?如果我们可以免除zip文件,那么我们可以使用一堆经过良好测试的工具 - 主要是Module::Pluggable在目录树中查找匹配给定名称前缀的Perl模块,加载它们并返回它们。代替Java接口,您可以使用Moose roles,它的功能类似于接口和mixin,这意味着您可以强制每个模块提供某些方法,并且还可以免费为每个模块提供一些共享行为。角色也是内省的,因此您可以使用它们来区分应以不同方式运行的scriptlet /插件。

如果zip文件非常重要,我仍然可以看到一种方法,可以使用@INC钩子使整个事情工作(谢天谢地,Module :: Pluggable最近添加了支持以更好地发挥它们),但复杂性开始接近&#34;这是我的咨询费率&#34;水平。

答案 1 :(得分:0)

首先,您必须从zip文件中提取代码。使用Archive :: Extract,您可以将提取的文件转储到已知目录中。

如果使用 lib 编译指示将include路径设置为此目录,并且如果您在zip文件Perl模块文件中创建文件,则可以将文件加载到主程序中 需要Package :: Name 语句。这是一个运行时语句。 如果要加载具有相同名称的第二个模块,则可以清除模块存储并将其从%INC中删除。

这样的功能
sub unload_module {
    my $module = shift;
    my $inc_key = $module;

    # Convert $inc_key into the correct format for %INC
    $inc_key =~ s/::/\//g;
    $inc_key .= '.pm';

    # Remove from %INC
    delete $INC{$inc_key};

    # Clear the Stash
    delete %{"$module::"};
}

这假设您不想将任何内容导入主包名称空间