如何使用只有在运行时才知道的Perl包?

如何使用只有在运行时才知道的Perl包?,perl,runtime,packages,require,Perl,Runtime,Packages,Require,我有一个Perl程序,需要使用包(我也编写)。其中一些包仅在运行时选择(基于某些环境变量)。当然,我不想在我的代码中为所有这些包添加一个“use”行,但基于这个变量,只有一个“use”行,类似于: use $ENV{a}; 不幸的是,这当然行不通。有什么办法吗 提前感谢,, 奥伦 “use”在这里不起作用,因为它只在eval的上下文中导入 正如@Manni所说,实际上,最好使用require。引用自man perlfunc: If EXPR is a bareword, the require

我有一个Perl程序,需要使用包(我也编写)。其中一些包仅在运行时选择(基于某些环境变量)。当然,我不想在我的代码中为所有这些包添加一个“use”行,但基于这个变量,只有一个“use”行,类似于:

use $ENV{a};
不幸的是,这当然行不通。有什么办法吗

提前感谢,, 奥伦

use
”在这里不起作用,因为它只在
eval
的上下文中导入

正如@Manni所说,实际上,最好使用require。引用自
man perlfunc

If EXPR is a bareword, the require assumes a ".pm" extension and replaces "::" with "/" in the filename for you, to make it easy to load standard modules. This form of loading of modules does not risk altering your namespace. In other words, if you try this: require Foo::Bar; # a splendid bareword The require function will actually look for the "Foo/Bar.pm" file in the directories specified in the @INC array. But if you try this: $class = 'Foo::Bar'; require $class; # $class is not a bareword #or require "Foo::Bar"; # not a bareword because of the "" The require function will look for the "Foo::Bar" file in the @INC array and will complain about not finding "Foo::Bar" there. In this case you can do: eval "require $class"; 如果EXPR是一个裸字,则require将假定扩展名为“.pm”,并且 将文件名中的“:”替换为“/”,以便 加载标准模块。这种形式的模块加载不会 冒着更改名称空间的风险。 换句话说,如果您尝试以下方法: 需要Foo::Bar;#华丽的空话 require函数实际上会查找“Foo/Bar.pm”文件 在@INC数组中指定的目录中。 但如果你尝试这样做: $class='Foo::Bar'; 需要$class;#$阶级不是空话 #或 需要“Foo::Bar”;#因为“”而不是一句空话 require函数将在@INC中查找“Foo::Bar”文件 数组,并会抱怨在那里找不到“Foo::Bar”。在这个 在这种情况下,您可以: eval“需要$class”;
如果您不希望在编译时使用
require
而不是
use
,则可能需要使用
require
,然后手动导入可能需要的任何符号。请参阅(来自谷歌图书)以获得有关可用于实现所需功能的方法的详细讨论。

“use”语句在编译时运行,而不是在运行时运行。您将需要您的模块:

my $module = "Foo::Bar";
eval "require $module";
我会用。它有require和use两种方法来使用包。use方法还将调用包的导入

use UNIVERSAL::require;
$ENV{a}->use or die 'Could not import package:  ' . $@;

我认为运行时加载的模块可以是插件。我有这样的问题,有一些特定的模块在运行时作为插件加载


也许您需要更改模块的逻辑,但它运行良好,可扩展性也很好(我的应用程序最初有四个模块,现在有二十个,而且还在增长)。

使用核心模块怎么样

以你的例子:

use Module::Load;
load $ENV{a};
“模块::加载-运行时需要同时加载模块和文件”

“加载使您无需知道是否需要文件或模块。”


如果失败,它将以类似“在@INC中找不到xxx(@INC包含:…”许多年后,
eval“use$mod_name”;
似乎工作正常(至少在5.8.8)

eval“require$mod_name”;
相比,它的优势在于加载模块的默认导出是自动导入的;换句话说:

eval“使用$mod\u名称”

较短的长度等于

eval“需要$mod_name”;$mod_name->import();

下面是一个test命令,它通过env.variable
mod_name
传递模块的名称,加载并导入模块,然后使用导入的函数(假设是类似于POSIX的shell):


我可能遗漏了一些细节;如果是这样,请告诉我。

我们真的应该链接到盗版书籍吗?将链接更改为转到Google books,我认为Google books有权以“预览”的形式发布这些信息。谢谢。这感觉好多了。这很好,我想知道为什么PCB中没有包括它?这和评估需求之间有什么区别吗?你还需要手动导入符号吗?我看到了引文,Nathan。但是在我们的情况下,哪里说需求更好?你是说“更好”像“不那么深奥”吗/规范化?一个问题是,虽然它看起来像“使用”,但实际上只是一个“要求”,似乎没有发生导入。@Manni,这就是我的意思。它更规范。它确实导入,不幸的是,它导入了eval块。
use Module::Load;
load $ENV{a};
 $ mod_name='Data::Dumper' perl -e 'eval "use $ENV{mod_name}"; print Dumper("hi!")'
 $VAR1 = 'hi!';