我试图弄清楚如何在Perl中使用在嵌套子目录中组织的嵌套模块。我的意思是,test.pl程序使用Foo模块,而该模块又使用另一个Bar模块,依此类推...让我们举个小例子,文件可以组织在这样的目录中:
./test.pl
./lib/Foo.pm
./lib/common/Bar.pm
首先想到的是像这样在test.pl中使用FindBin模块:
use FindBin;
use lib "$FindBin::RealBin/lib/.";
use Foo;
但是,如果要在Foo中执行相同的操作以“使用Bar”,则需要包括test.pl程序中的所有相对路径,包括“ / lib”段。这意味着Foo需要知道他到调用程序的相对路径。这迫使目录结构具有某种刚性。例如,您不能简单地将自定义模块复制并粘贴到任意位置并调用它。此外,它需要安装FindBin模块才能正常工作。
为了解决此问题,谷歌搜索后找到了以下解决方案:BEGIN solution,它直接向@INC添加路径。考虑到这一点,解决方案可能是:
./ test.pl
#!/usr/bin/perl
use strict;
use warnings;
# Include lib in @INC
BEGIN {
use File::Basename;
my($filename, $dirs, $suffix) = fileparse(__FILE__);
my $common_path = $dirs."lib/.";
unshift(@main::INC, $common_path) ;
}
use Foo;
print "Inside: $Foo::message";
./ lib / Foo.pm
package Foo;
# Include Common library
BEGIN {
use File::Basename;
my($filename, $dirs, $suffix) = fileparse(__FILE__);
$common_path = $dirs."common/.";
unshift(@main::INC, $common_path) ;
}
use Bar;
$message = " Foo > $Bar::message";
1;
./ lib / common / Bar.pm
package Bar;
$message = "Bar";
1;
正在执行。/test.pl应打印:
Inside: Foo > Bar
您可以将任意数量的模块嵌套在各自的目录中(我测试了三个级别),更好的是,在不中断功能的情况下,在任意路径下复制和粘贴。但是,我不知道此方法是否建议使用或有任何缺点(我不熟悉perl)。例如,建议像这样直接编辑@INC吗?建议使用BEGIN代码块吗?或者,是否有更好的方法可以做到这一点(允许在模块目录结构的任意点复制和粘贴目录),因此可以在不接触模块内部代码的情况下运行?
请勿更改模块中的@INC
。将其留给脚本。
use FindBin qw( $RealBin );
use lib "$RealBin/lib", "$RealBin/lib/common";
这意味着Foo需要知道他到调用程序的相对路径。
如果脚本和其他库之间都存在,那不是问题,使用use lib
是有意义的。
否则,它只是任何脚本都可以使用的模块,不应使用use lib
。相反,应将其安装到标准安装目录(或由env var PERL5LIB
指定的自定义目录)中。
顺便说一句,您可能不应该将common
放在lib
内。这意味着您可以执行use common::Bar;
,这是错误的。