Perl:使用在嵌套子目录中组织的自定义嵌套模块

标签 perl nested relative-path perl-module

我试图弄清楚如何使用在 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/

相关文章:

r - 仅将嵌套数据帧的一列除以整数值

php - XAMPP 相对 URL 无法正常工作

sql - 在Sql Bulk Insert语句中,我们可以使用相对路径(files\a.txt)而不是绝对路径(c :\abc\a. txt)或网络通用路径(\\abc\a.txt)吗?

perl - 在perl中将列表上下文结果转换为一行中的数组?

perl - 这条线在 perl 中是什么意思?

perl - Perl 非面向对象的渗透测试

c# - 通过反射生成嵌套类的实例 C#

ruby-on-rails - 无法修改关联 'Survey#answers',因为它经历了多个其他关联

asp.net - IIS URL 重写模块 : Url. Content() 无法正确解析 CSS/图像路径

perl - 这不是数组引用吗?为什么它不是数组引用?