我有一个perl模块.pm文件包含我的子程序,它看起来像这样:
package test;
use strict;
use vars qw($VERSION @ISA @EXPORT $ERROR $NAME);
require Exporter;
@ISA = qw(Exporter);
@EXPORT = (
sub1
sub2
err1
err2
);
#...etc...
Run Code Online (Sandbox Code Playgroud)
现在我有一个pl文件,需要导入子例程,但不是每个子例程,只有它们在配置列表中.例如:
@subs = ('sub1', 'sub2'); # need to load sub1 & sub2, but do not load err1 & err2
Run Code Online (Sandbox Code Playgroud)
要么
@subs = ('sub1', 'err1'); # need to load sub1 & err1, but do not load sub2 & err2
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?
我试图这样做,但没有工作:
my @subs = ('sub1', 'sub2');
use test @subs;
Run Code Online (Sandbox Code Playgroud)
有没有办法只加载所需的功能?所需要的是从SQL或配置文件或任何其他方式读取...
你的代码的原因:
my @subs = ('sub1', 'sub2');
use test @subs;
Run Code Online (Sandbox Code Playgroud)
不起作用的是,use语句在解析期间,在(几乎)任何其他代码之前立即进行评估.因此,代码的第二行实际上在第一行之前运行,因此@subs在那时仍然是空的.
这将工作:
my @subs;
BEGIN { @subs = ('sub1', 'sub2'); }
use test @subs;
Run Code Online (Sandbox Code Playgroud)
就像这样:
BEGIN {
my @subs = ('sub1', 'sub2');
require test;
test->import(@subs);
}
Run Code Online (Sandbox Code Playgroud)
在前一版本中,该BEGIN块用于使分配@subs在解析期间已经发生; 在第二个版本中,整个代码放在一个BEGIN块中,该use语句将替换为其运行时等效项(require+ import).
但是,您可能首先没有任何理由这样做.当你加载一个模块时,无论如何都加载了它的所有代码,*所以你实际上并没有通过导入模块提供的一些功能来保存任何内存.实际上,几乎没有导入模块提供的所有内容的唯一真正原因是避免可能尝试导出具有相同名称的函数或使用您自己的函数的模块之间的冲突.
在任何情况下,它总是*可以调用模块中的功能,而无需输入他们所有,只是由模块名作为前缀和他们::.所以,而不是:
use test qw(foo bar);
foo();
bar();
Run Code Online (Sandbox Code Playgroud)
你可以这样做:
use test ();
test::foo();
test::bar();
Run Code Online (Sandbox Code Playgroud)
*)从技术上讲,Perl 中保证的东西很少,并且模块很可能实现某种延迟加载机制,只在导入时才创建函数(或从另一个模块加载它们).但这需要一个自定义import(和/或AUTOLOAD)方法; 对于使用Exporter的普通模块,上面的简化描述是正确的.