【发布时间】:2020-09-11 14:33:48
【问题描述】:
我试图弄清楚如何使用 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 代码块?或者,有没有更好的方法来做到这一点(允许在模块目录结构的任意点复制和粘贴目录),这样它就可以在不触及模块内部代码的情况下工作?
【问题讨论】:
标签: perl nested relative-path perl-module