在perl中动态加载模块
Load modules dynmically in perl
我想将很多函数存储在一个文件夹中,并将它们包含在主脚本中。
例如,我有这个库 ABC1.pm:
package ABC1;
use strict;
use warnings;
my $var1 = 'abc1';
sub func1 {
print "$var1\n";
}
return 1;
另一个叫 ABC2.pm:
package ABC2;
use strict;
use warnings;
my $var2 = 'abc2';
sub func2 {
print "$var2\n";
}
return 1;
两个文件都保存在文件夹库下
现在我 运行 主脚本查看文件夹中的所有文件并尝试加载它们:
#!/usr/bin/env perl
#script.pl
use strict;
use warnings;
BEGIN {push @INC, './libraries/.'}
# use ABC1;
# use ABC2;
my $dir = './libraries';
my @libraries;
opendir(DIR, $dir) or die $!;
while (my $file = readdir(DIR)) {
next if ($file =~ m/^\./);
print "$file\n";
$file =~ s/\.pm$//;
print "$file\n";
push @libraries, $file;
}
eval {
foreach my $library (@libraries){
require $library;
$library->import();
}
1;
} or do {
my $error = $@;
print $error;
};
ABC1->func1();
ABC2->func2();
如果我只是 运行 它和手动输入的使用语句,它就可以工作。但是,如果我想使用未注释的代码,则会出现以下错误:
Can't locate ABC1 in @INC (@INC contains:
C:/Strawberry/perl/site/lib/MSWin32-x64-multi-thread
C:/Strawberry/perl/site/lib C:/Strawberry/perl/vendor/lib
C:/Strawberry/perl/lib . ./libraries/. ./libraries/.) at abc.pl line
25. Can't locate object method "func1" via package "ABC1" (perhaps you forgot to load "ABC1"?) at abc.pl line 34.
但是路径库显示在@INC中,所以我不明白是怎么回事。
虽然 use MODULE
和 require MODULE
需要模块名称,但 require
的 require EXPR
语法需要文件路径。
可以是相对于@INC
中路径的路径。
require "Foo/Bar.pm";
可以是相对于当前目录的路径。
require "./Foo/Bar.pm";
可以是绝对路径
require "/some/dir/Foo/Bar.pm";
已修复并清理:
#!/usr/bin/env perl
use strict;
use warnings;
use FindBin qw( $RealBin ); # Get the location of this program.
my $plugins_dir_qfn = "$RealBin/libraries";
my @libraries;
opendir(my $dh, $plugins_dir_qfn) or die $!;
while (my $fn = readdir($dh)) {
next if $fn =~ /^\./ || $fn !~ /\.pm\z/;
my $qfn = "$plugins_dir_qfn/$fn";
#print "$qfn\n";
eval { require $qfn; }
or warn("Can't load \"$qfn\": $@");
}
ABC1->func1();
ABC2->func2();
我想将很多函数存储在一个文件夹中,并将它们包含在主脚本中。
例如,我有这个库 ABC1.pm:
package ABC1;
use strict;
use warnings;
my $var1 = 'abc1';
sub func1 {
print "$var1\n";
}
return 1;
另一个叫 ABC2.pm:
package ABC2;
use strict;
use warnings;
my $var2 = 'abc2';
sub func2 {
print "$var2\n";
}
return 1;
两个文件都保存在文件夹库下 现在我 运行 主脚本查看文件夹中的所有文件并尝试加载它们:
#!/usr/bin/env perl
#script.pl
use strict;
use warnings;
BEGIN {push @INC, './libraries/.'}
# use ABC1;
# use ABC2;
my $dir = './libraries';
my @libraries;
opendir(DIR, $dir) or die $!;
while (my $file = readdir(DIR)) {
next if ($file =~ m/^\./);
print "$file\n";
$file =~ s/\.pm$//;
print "$file\n";
push @libraries, $file;
}
eval {
foreach my $library (@libraries){
require $library;
$library->import();
}
1;
} or do {
my $error = $@;
print $error;
};
ABC1->func1();
ABC2->func2();
如果我只是 运行 它和手动输入的使用语句,它就可以工作。但是,如果我想使用未注释的代码,则会出现以下错误:
Can't locate ABC1 in @INC (@INC contains: C:/Strawberry/perl/site/lib/MSWin32-x64-multi-thread C:/Strawberry/perl/site/lib C:/Strawberry/perl/vendor/lib C:/Strawberry/perl/lib . ./libraries/. ./libraries/.) at abc.pl line 25. Can't locate object method "func1" via package "ABC1" (perhaps you forgot to load "ABC1"?) at abc.pl line 34.
但是路径库显示在@INC中,所以我不明白是怎么回事。
虽然 use MODULE
和 require MODULE
需要模块名称,但 require
的 require EXPR
语法需要文件路径。
可以是相对于@INC
中路径的路径。
require "Foo/Bar.pm";
可以是相对于当前目录的路径。
require "./Foo/Bar.pm";
可以是绝对路径
require "/some/dir/Foo/Bar.pm";
已修复并清理:
#!/usr/bin/env perl
use strict;
use warnings;
use FindBin qw( $RealBin ); # Get the location of this program.
my $plugins_dir_qfn = "$RealBin/libraries";
my @libraries;
opendir(my $dh, $plugins_dir_qfn) or die $!;
while (my $fn = readdir($dh)) {
next if $fn =~ /^\./ || $fn !~ /\.pm\z/;
my $qfn = "$plugins_dir_qfn/$fn";
#print "$qfn\n";
eval { require $qfn; }
or warn("Can't load \"$qfn\": $@");
}
ABC1->func1();
ABC2->func2();