我在Perl中实现了一个相当复杂的数据结构。这已被分解为大约20个班级。基本上,只要你想使用其中一个类,就需要使用它们。
现在,如果有人想要使用这种数据结构,他们需要做类似的事情:
use Component::Root;
use Component::Foo;
use Component::Bar;
use Component::Baz;
use Component::Flib;
use Component::Zen;
use Component::Zen::Foo;
use Component::Zen::Bar;
use Component::Zen::Baz;
... # 15 more of these...
use Component::Last;
能够操纵它的所有部分。如何编写一个为用户执行此操作的模块,因此他们所要做的只是
use Component;
导入所有其他模块?
在这种特殊情况下,模块都是类,没有导出。
答案 0 :(得分:6)
如果这些只是类(即当它们use
时它们不导出任何函数或变量),那么真正重要的是它们已被加载。
只需创建Component.pm
:
package Component;
our $VERSION = '1.00';
use Component::Root;
use Component::Foo;
use Component::Bar;
use Component::Baz;
use Component::Flib;
use Component::Zen;
use Component::Zen::Foo;
use Component::Zen::Bar;
use Component::Zen::Baz;
... # 15 more of these...
use Component::Last;
1; # Package return value
您不需要Exporter
或类似内容。
然而,将这些use
语句放入根节点的类或创建的use
语句中,可能更有意义,而不是只有use Component::Root;
my $root = Component::Root->new(...);
语句的模块。数据结构。也就是说,人们会想说:
use Component qw(build_structure);
my $root = build_structure(...);
或
use Component;
my $root = Component::Root->new(...);
取决于您的数据结构的正常创建方式。人们写作可能有点令人困惑:
new
但它实际上取决于您的API的样子。如果有许多人可能正在调用use Component
,那么{{1}}可能是最佳选择。
答案 1 :(得分:1)
您可以对 export_to_level
的所有软件包使用Exporter
方法。
MyPackage->export_to_level($where_to_export, $package, @what_to_export);
您也可以导出导入的所有符号。
use PackageA qw<Huey Dewey Louie>;
...
our @ISA = qw<Exporter>; #inherit Exporter
our @EXPORT = qw<Huey Dewey Louie>;
但是,如果您不想导出任何符号,并且只想加载模块,那么只需在上面包含那些use
语句,并在其中包含任何包进程将能够将它们实例化为类,比如它们都是OO模块。
如果它们已成功加载,它们将存在于%INC
和符号表中。
答案 2 :(得分:0)
Moose::Exporter似乎是这样做的,尽管你所有其他模块也必须使用它。
在Component
:
Moose::Exporter->setup_import_methods(
also => [qw/Component::Root Component::..*/],
);
答案 3 :(得分:0)
如果模块没有导出任何东西并且没有导入方法(与cjm的答案相同的要求),你只需要加载模块而不需要导入:
package Component;
our $VERSION = '1.00';
require Component::Root;
require Component::Foo;
require Component::Bar;
require Component::Baz;
require Component::Flib;
require Component::Zen;
require Component::Zen::Foo;
require Component::Zen::Bar;
require Component::Zen::Baz;
... # 15 more of these...
require Component::Last;
1; # Package return value
模块的用户只会这样做:
require Component;
但是,如果某些模块执行导出,则必须调用其import
方法。因此,您需要在import
模块中添加一个Component
方法来调用它们:
sub import
{
Component::Root->import;
Component::Foo->import;
...
}
所以模块用户必须use
:
use Component;
请注意,如果导入的模块必须在导入器的上下文中插入符号,则可能必须使用其他一些技巧。例如,参见POE's import如何做到这一点。
答案 4 :(得分:0)
Modern::Perl模块自称“使用一个命令启用Modern Perl的所有功能”,其中该命令为
use Modern::Perl;
并且这些功能
目前,这只启用了strict和warnings pragma,以及Perl 5.10中提供的所有功能。它还启用C3方法解析顺序;请参阅perldoc mro以获得解释。
对于一行代码来说,这很多,根据perlmod documentation完全等同于
BEGIN { require Module; import Module; }
考虑Modern :: Perl的implementation:
package Modern::Perl;
our $VERSION = '1.03';
use 5.010_000;
use strict;
use warnings;
use mro ();
use feature ();
sub import {
warnings->import();
strict->import();
feature->import( ':5.10' );
mro::set_mro( scalar caller(), 'c3' );
}
1; # End of Modern::Perl
根据您的情况,从您的顶级模块use
调整您想要加载的所有其他模块,并从MyTopLevelModule::import
调用其导入(如果有)。
请注意,您不一定需要复制
use 5.010_000;
进入MyTopLevelModule.pm
,但这是一个好主意!根据{{3}}:
在特殊的
use VERSION
形式中, VERSION 可以是正小数,例如5.006
,将与$]
进行比较,或者是v -v5.6.1
形式的字符串,将与$^V
(又名$PERL_VERSION
)进行比较。如果 VERSION 大于当前Perl解释器的版本,则会引发异常; Perl不会尝试解析文件的其余部分。与require
比较,{{1}}可以在运行时进行类似的检查。