我正在跟踪有关perl Web服务的question。我设法从主程序加载和执行模块。每个模块都是这样的:
#!/usr/bin/perl
package NiMbox::perlet::skeleton;
use strict;
use warnings;
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(%DEFINITION main secondary);
our %DEFINITION;
$DEFINITION{'main'} = {
summary => 'skeleton main',
description => 'long skeleton main description',
args => { 'box' => {}, 'other' => {} }
};
$DEFINITION{'secondary'} = {
summary => 'skeleton secondary',
description => 'long skeleton secondary description'
};
sub main {
print "main...\n";
}
sub secondary {
print "secondary...\n"
}
1;
然后可以像下面这样完成这些模块的调用:
use NiMbox::perlet::skeleton;
my %DEFINITION = %NiMbox::perlet::skeleton::DEFINITION;
foreach my $s (keys %DEFINITION) {
print "calling sub '$s'\n";
NiMbox::perlet::skeleton->$s();
}
我如何以一种可以执行类似以下操作的方式摆脱
NiMbox::perlet:skeleton
的直接调用(该方法不起作用,但说明了我需要做的事情):my $perlet = 'skeleton';
use NiMbox::perlet::$perlet;
my %DEFINITION = %NiMbox::perlet::$perlet::DEFINITION;
foreach my $s (keys %DEFINITION) {
print "calling sub '$s'\n";
NiMbox::perlet::$perlet->$s();
}
由于我非常接近,所以我宁愿查看此示例中缺少的内容,也不愿使用其他库。有任何想法吗?
最佳答案
我相信您正在寻找的是Exporter或它的许多后续模块。我看到您已经在模块中使用它了,但是您没有使用它来获取%DEFINITION
。您可以这样做:
use NiMbox::perlet::skeleton qw(%DEFINITION);
foreach my $s (keys %DEFINITION) {
print "calling sub '$s'\n";
NiMbox::perlet::skeleton->$s();
}
这将
%NiMbox::perlet::skeleton::DEFINITION
别名为%DEFINITION
并节省了大量输入。为了能够使用
%DEFINITION
的变量定义,您可以使用“符号引用”通过名称来引用变量...但是这些变量充满了危险。同样,导出全局变量意味着一次只能在给定的 namespace 中只有一个。我们可以做得更好。我的建议是改为将
%DEFINITION
哈希更改为definition()
类方法,该方法返回对%DEFINITION的引用。您可以返回散列,但是参考避免浪费时间复制。package NiMbox::perlet::skeleton;
use strict;
use warnings;
my %DEFINITION = ...;
sub definition {
return \%DEFINITION;
}
现在,您可以调用该方法并获取哈希引用。
use NiMbox::perlet::skeleton;
my $definition = NiMbox::perlet::skeleton->definition;
foreach my $s (keys %$definition) {
print "calling sub '$s'\n";
NiMbox::perlet::skeleton->$s();
}
动态地执行此操作,唯一的技巧是加载类。您可以
eval "require $class" or die $@
,但这会带来安全隐患。 UNIVERSAL::require或Module::Load可以为您更好地处理该问题。use Module::Load;
my $class = 'NiMbox::perlet::skeleton';
load $class;
my $definition = $class->definition;
foreach my $s (keys %$definition) {
print "calling sub '$s'\n";
$class->$s();
}
关于perl - 如何在Perl中动态加载模块并执行方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6525524/