动态加载Perl模块 [英] Dynamically loading Perl modules
问题描述
我正在尝试制作一个可扩展的系统,我可以编写一个新的模块来作为一个处理程序。我希望程序自动加载放入Handlers目录并符合Moose :: Role界面的任何新的.pm文件。
我想知道是否有是一个Perl模块还是更多的Moose认证方式自动执行?这是我迄今为止所建立的,但似乎有点冗长,而且必须有一个更简单的方法。
处理程序.pl
包含:
#!/ usr / bin / perl
use Handler;
使用Data :: Dumper;
我的$ base_handler = Handler-> new();
$ base_handler-> load_modules('SysG / Handler');
print Dumper($ base_handler);
Handler.pm
包含:
package Handler;
使用麋;
有'handlers'=> (traits => ['Array'],handles => {add_handler =>'push'});
sub load_modules {
my($ self,$ dir)= @_;
push(@INC,$ dir);
我的@modules = find_modules_to_load($ dir);
eval {
#请注意,这种排序很重要。处理顺序将至关重要。
#排序意味着排序顺序
foreach我的$ module(sort @modules){
(我的$ file = $ module)=〜s | :: | / | g;
print关于加载$ file.pm for module $ module\\\
;
需要$文件。 '。下午';
$ module-> import();
my $ obj = $ module-> new();
$ self-> add_handler($ obj);
1;
}
}或做{
我的$错误= $ @;
print加载模块时出错:$ errorif $ error;
};
}
sub find_modules_to_load {
my($ dir)= @_;
我的@files = glob($ dir / *。pm);
我的$ namespace = $ dir;
$ namespace =〜s / \ // :: / g;
#获取叶子名称并添加System :: Module命名空间
my @modules = map {s /.* \ /(.*)。pm // g; $ {命名空间} :: $ 1; } @files;
dieERROR:在$ dir\\\
中找不到分类器模块,除非@modules;
return @modules;
}
1;
然后我创建了一个名为SysG / Handler的目录,并添加了两个.pm文件,通常将符合一个Moose ::角色(好像定义一个必须被粘贴的界面)。
SysG :: Handler :: 0001_HandleX.pm
stub包含:
包SysG :: Handler :: 0001_HandleX;
使用麋;
1;
SysG :: Handler :: 0002_HandleX.pm
stub包含:
包SysG :: Handler :: 0002_HandleY;
使用麋;
1;将所有这一切放在一起,Data :: Dumper的结果是: $ VAR1 = bless({
'handlers'=> [
bless({},'SysG :: Handler :: 0001_HandleX '),
bless({},'SysG :: Handler :: 0002_HandleY')
]
},'Handler');
所以,现在我重复一下我的原始问题:必须有一个更简单的方法,或一个模块或任何Moose专家能够在这里帮助吗?
解决方案
I am trying to make an extensible system whereby I can code up a new module to be a handler. I want the program to automatically load any new .pm file that is put into the Handlers directory and conforms to a Moose::Role interface.
I'm wondering whether there is a Perl module or a more Moose sanctioned way to do this automatically? Here is what I have built so far, but it seems a little verbose and there has got to be a simpler way to do it.
handler.pl
contains:
#!/usr/bin/perl
use Handler;
use Data::Dumper;
my $base_handler = Handler->new();
$base_handler->load_modules('SysG/Handler');
print Dumper($base_handler);
Handler.pm
contains:
package Handler;
use Moose;
has 'handlers' => ( traits => ['Array'], handles => { add_handler => 'push' } );
sub load_modules {
my ($self,$dir) = @_;
push(@INC, $dir);
my @modules = find_modules_to_load($dir);
eval {
# Note that this sort is important. The processing order will be critically important.
# The sort implies the sort order
foreach my $module ( sort @modules) {
(my $file = $module) =~ s|::|/|g;
print "About to load $file.pm for module $module\n" ;
require $file . '.pm';
$module->import();
my $obj = $module->new();
$self->add_handler($obj);
1;
}
} or do {
my $error = $@;
print "Error loading modules: $error" if $error;
};
}
sub find_modules_to_load {
my ($dir) = @_;
my @files = glob("$dir/*.pm");
my $namespace = $dir;
$namespace =~ s/\//::/g;
# Get the leaf name and add the System::Module namespace to it
my @modules = map { s/.*\/(.*).pm//g; "${namespace}::$1"; } @files;
die "ERROR: No classifier modules found in $dir\n" unless @modules;
return @modules;
}
1;
Then I have made a directory called SysG/Handler and added two .pm files which ordinarily will conform to a Moose::Role (as if to define an interface that must be adhered too).
The SysG::Handler::0001_HandleX.pm
stub contains:
package SysG::Handler::0001_HandleX;
use Moose;
1;
The SysG::Handler::0002_HandleX.pm
stub contains:
package SysG::Handler::0002_HandleY;
use Moose;
1;
Put all this together and the Data::Dumper result is:
$VAR1 = bless( {
'handlers' => [
bless( {}, 'SysG::Handler::0001_HandleX' ),
bless( {}, 'SysG::Handler::0002_HandleY' )
]
}, 'Handler' );
So, now I repeat my original question: There must be a simpler way, or a module or a Moose way to automatically load any modules in a specific directory.
Any Moose experts able to help out here?
解决方案
这篇关于动态加载Perl模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!