如何使用仅在运行时已知的 Perl 包?
我有一个 Perl 程序,需要使用包(我也编写)。 其中一些包仅在运行时选择(基于某些环境变量)。 当然,我不想在代码中为所有这些包添加一个“use”行,但只有一个基于此变量的“use”行,例如:
use $ENV{a};
不幸的是,这当然不起作用。 关于如何做到这一点有什么想法吗?
提前致谢, 奥伦
I have a Perl program, that needs to use packages (that I also write). Some of those packages are only chosen in Runtime (based on some environment variable). I don't want to put in my code a "use" line for all of those packages, of course, but only one "use" line, based on this variable, something like:
use $ENV{a};
Unfortunately, this doesn't work, of course. Any ideas on how to do this?
Thanks in advance,
Oren
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
“
use
”在这里效果不佳,因为它仅在eval
的上下文中导入。正如@Manni 所说,实际上,最好使用 require。 引用自
man perlfunc
:"
use
" doesn't work well here because it only imports in the context of theeval
.As @Manni said, actually, it's better to use require. Quoting from
man perlfunc
:“use”语句在编译时运行,而不是在运行时运行。 您将需要需要您的模块:
"use" Statements are run at compilation time, not at run time. You will need to require your modules instead:
我会使用UNIVERSAL::require。 它具有 require 和 use 方法来使用包。 use 方法还将调用包的import。
I would use UNIVERSAL::require. It has both require and use methods to use a package. The use method will also call import for the package.
如果您不希望在编译时发生这种情况,您可能需要使用
require
而不是use
,然后手动导入您可能需要的任何符号。 请参阅此 Perl Cookbook 链接(来自 Google 图书),详细讨论了可用于实现所需目标的方法。You probably want to use
require
instead ofuse
if you don't want it to happen at compile time, and then manually import any symbols you might need. See this link to the Perl Cookbook (from Google Books) for a good discussion of methods you can use to achieve what you want.我认为在运行时加载的模块可以是插件。 我遇到这种问题,在某些情况下有特定的模块,这些模块在运行时作为插件加载 模块::Pluggable。
也许您需要更改模块的逻辑,但它的工作原理和扩展性非常好(我的应用程序从四个模块开始,现在有二十个,而且还在不断增长)。
I think that a module loaded in runtime can be a Plugin. I have this kind of problem, having specific modules to some cases that are loaded in run time as plugins with Module::Pluggable.
Maybe you need to change the logic of your modules, but it works and scale very well (my app started with four modules and now have twenty and it's growing).
如何使用核心模块 Module::Load
以您的示例:
“Module::Load - 模块和文件的运行时要求”
“加载消除了知道您是否试图要求文件或模块的需要。”
如果失败,它将因类似“无法在 @INC 中定位 xxx(@INC 包含:...”)而终止。
How about using the core module Module::Load
With your example:
"Module::Load - runtime require of both modules and files"
"load eliminates the need to know whether you are trying to require either a file or a module."
If it fails it will die with something of the like "Can't locate xxx in @INC (@INC contains: ...".
许多年后,
eval "use $mod_name";
似乎工作得很好(至少从 5.8.8 开始)。相对于
eval "require $mod_name";
的优点是加载模块的默认导出是自动导入的; 换句话说:eval "use $mod_name";
的缩写形式
是
eval "require $mod_name"; ; $mod_name->import();
这是一个测试命令,它通过 env 传递模块的名称。 变量
mod_name
,加载并导入模块,然后使用导入的函数(假设有一个类似 POSIX 的 shell):我可能会遗漏一些细节; 如果是这样,请告诉我。
Many years later,
eval "use $mod_name";
seems to work just fine (as of at least 5.8.8).The advantage over
eval "require $mod_name";
is that the loaded module's default exports are automatically imported; in other words:eval "use $mod_name";
is the shorter equivalent of
eval "require $mod_name"; $mod_name->import();
Here's a test command, which passes the name of the module via env. variable
mod_name
, loads and imports the module, then uses an imported function (assumes a POSIX-like shell):I may be missing subtleties; if so, please let me know.