我试图弄清楚如何使用在 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";
That means Foo needs to be aware of his relative path to the calling program.
如果脚本和其他库都存在,那不是问题,使用
use lib
说得通。否则,它只是一个可供任何脚本使用的模块,
use lib
不应该使用。相反,它应该安装到标准安装目录(或由 env var PERL5LIB
指定的自定义目录)。顺便说一句,你可能不应该把
common
lib
内部.这意味着您可以执行 use common::Bar;
,这是错误的。
关于Perl:使用在嵌套子目录中组织的自定义嵌套模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61994200/