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

问题描述 投票:0回答:1

我试图弄清楚如何在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
1个回答
0
投票

请勿更改模块中的@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;,这是错误的。

© www.soinside.com 2019 - 2024. All rights reserved.