Perl`use qw`或从pm文件导入子例程

Perl`use qw`或从pm文件导入子例程,perl,perl-module,Perl,Perl Module,我有一个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... 现在我有了一个pl文件,需要导入哪些子例程,但不是每个子例程,只要它们在配置列

我有一个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...
现在我有了一个
pl
文件,需要导入哪些子例程,但不是每个子例程,只要它们在配置列表中。例如:

@subs = ('sub1', 'sub2'); # need to load sub1 & sub2, but do not load err1 & err2

我该怎么做

我试着这样做,但没有成功:

my @subs = ('sub1', 'sub2');
use test @subs;

有没有办法只加载所需的函数?需要的是从SQL或config文件或任何其他方式读取…

首先,所有Perl全局变量都应该使用大写字母,因此包的名称应该以大写字母开头,并且文件的名称应该更改为一致

其次,如果您直接加载它的
import
方法,而不是从
Exporter
继承,那么开销会小得多

我不知道
err1
err2
是什么类型的东西,但是应该在数组
@EXPORT\u OK
中放置可选的导出

这使您的模块看起来像这样

use strict;
use warnings;

use Test qw/ sub1 /;

sub1;
测试.pm

package Test;

use strict;
use warnings;

use Exporter 'import';

our @EXPORT_OK = qw/ sub1 sub2 /;

sub sub1 {
  print "sub1\n";
}

sub sub2 {
  print "sub2\n";
}
一个使用它的程序看起来是这样的

use strict;
use warnings;

use Test qw/ sub1 /;

sub1;
输出

sub1
您输入代码的原因:

my @subs = ('sub1', 'sub2');
use test @subs;
不起作用的是,在解析过程中,在(几乎)任何其他代码之前立即对语句求值。因此,代码的第二行实际上在第一行之前运行,因此
@subs
此时仍然为空

这将有助于:

因此:

BEGIN {
    my @subs = ('sub1', 'sub2');
    require test;
    test->import(@subs);
}
在前一个版本中,
BEGIN
块用于在解析过程中对
@subs
进行赋值;在第二个版本中,整个代码被放在
BEGIN
块中,
use
语句被替换为其运行时等效语句(
require
+
import


然而,你可能一开始就没有任何理由这么做。当您加载一个模块时,它的所有代码都会被加载,*因此您实际上不会通过导入模块提供的一些函数来节省内存。事实上,不导入模块提供的所有内容的唯一真正原因是为了避免模块之间的冲突,这些模块可能试图导出具有相同名称的函数,或者您自己的函数

在任何情况下,都可以*调用模块中的函数而不导入它们,只需在它们前面加上模块名和
。因此,不是:

use test qw(foo bar);
foo();
bar();
您只需执行以下操作:

use test ();
test::foo();
test::bar();


*)从技术上讲,Perl中保证的东西很少,而且模块很可能实现某种延迟加载机制,在导入函数时只创建函数(或从另一个模块加载函数)。但这需要一个自定义的
导入
(和/或
自动加载
)方法;对于使用的普通模块,上面的简化描述是正确的。

模块将SUB导入其他“名称空间”,以便可以通过其声明的名称而不是完全限定的名称来调用SUB。因此,与其尝试选择性地导入sub,不如用它们的全名来引用它们。(您的代码片段:
test::sub1()
test::sub2()
,等等)。此外,
@EXPORT
默认情况下会导出所有内容。因此,所有sub都已经在底层
pl
文件的公开中。当子模块处于
@EXPORT\u OK
@LinusKleen时,您可以有选择地导入:如果我使用此全名,则只将使用过的函数加载到内存中?否。您可以
使用该模块,然后引用其完全限定的子模块。导出它们只会让你不用用潜艇的“全名”来引用潜艇。这都是很好的建议,但我认为这并不能真正回答OP的问题。请看我的答案,我认为这是OP面临的实际问题。谢谢你的回答。下一个问题是如何使用perl模块和
使用
节省内存和编译时间?有可能吗?这可能是一个单独问题的主题,但首先,请参阅和模块以及。
use test ();
test::foo();
test::bar();