从Perl的全局区域导入模块

时间:2019-02-01 18:19:05

标签: perl

因此,我正在尝试将模块导入Perl包中,并尝试以最简洁的方式进行制作。首先,我阅读了之前的一些主题(例如:link)。

该模块位于以下路径:/p/disk/tools/perl/5.26.1/lib64/site_perl。该模块是Data::TreeDumper

我使用了FindBin模块来导入它:

BEGIN {
    use Exporter ();
    use vars qw(@ISA @EXPORT_OK  %EXPORT_TAGS);
    use FindBin;
    use lib "$FindBin::RealBin";
    use lib "$FindBin::Bin";
    use lib "$FindBin::Bin/../lib";
    use lib "/p/disk/tools/perl/5.26.1/lib64/site_perl";
    @ISA       = qw(Exporter);
    @EXPORT_OK = qw(# ALL subs
                   );
    %EXPORT_TAGS = (all => [@EXPORT_OK]);
}
use constants qw(:all);
use Data::TreeDumper;

它对我有用,但是路径是硬编码的。我想将路径包括在constants包(我的包)中。但这有点像圆,因为要使用常量(和路径),我需要先将其导入,然后再从哪里导入?嗯。

所以我想删除use lib "/p/disk/tools/perl/5.26.1/lib64/site_perl";行,然后以某种方式首先导入constants文件,然后执行以下操作:

use constants qw(:all);
use lib $PATH_TO_THE_MODULE; # represents path to the module area
use Data::TreeDumper;

但是它不起作用。有可能实现吗?

在尝试导入模块之前(不知道它是否已安装在全局位置),我先在本地安装了它,然后工作了。但我不想将非地雷模块与项目保留在同一目录中。因此,IT人士在全球范围内安装了该模块,而我只是问是否有可能以一种干净的方式导入它。

编辑:我正在尝试将路径/p/disk/tools/perl/5.26.1/lib64/site_perl插入到全局变量中的常量文件中(我们称之为$PATH_TO_THE_MODULE)。然后,我想从另一个包中导入constants包,所以我使用FindBin。然后,我想使用指向模块区域的$PATH_TO_THE_MODULE变量导入模块。所以它应该看起来像这样:

use constants qw(:all);
use lib $PATH_TO_THE_MODULE; # represents a path to the module area
use Data::TreeDumper;

但是它不起作用。我尝试切换到require,因为我知道require将动态使用。但它也会失败,Can't locate Data/TreeDumper.pm in @INC

因此,如果我们同时连接这两段代码,则会得到:

package test;
$|=1;
use strict;
use warnings;
BEGIN {
    use Exporter ();
    use vars qw(@ISA @EXPORT_OK  %EXPORT_TAGS);
    use FindBin;
    use lib "$FindBin::RealBin";
    use lib "$FindBin::Bin";
    use lib "$FindBin::Bin/../lib";
    @ISA       = qw(Exporter);
    @EXPORT_OK = qw(# ALL subs
                   );
    %EXPORT_TAGS = (all => [@EXPORT_OK]);
}
use constants qw(:all);
use lib $PATH_TO_THE_MODULE; # represents a path to the module area
use Data::TreeDumper;
print "Hi\n";

常量包:

package constants;
$|=1;
use strict;
use warnings;
BEGIN {
    use Exporter ();
    use vars qw(@ISA @EXPORT_OK  %EXPORT_TAGS);
    use FindBin;
    use lib "$FindBin::RealBin";
    use lib "$FindBin::Bin";
    use lib "$FindBin::Bin/../lib";
    @ISA       = qw(Exporter);
    @EXPORT_OK = qw($PATH_TO_THE_MODULE);
    %EXPORT_TAGS = (all => [@EXPORT_OK]);
}
our $PATH_TO_THE_MODULE = "/p/disk/tools/perl/5.26.1/lib64/site_perl";

如果我从use lib $PATH_TO_THE_MODULE;包中删除use Data::TreeDumper;test并打印$PATH_TO_THE_MODULE,它将按预期编译并打印路径。

1 个答案:

答案 0 :(得分:0)

您声称您的代码无效,这是因为$PATH_TO_THE_MODULE的初始化是在运行时发生的。

好了,你的代码做的工作,这是因为没有一个单一的编译阶段和单一的运行阶段。

假设您有以下脚本:

use constants ':all';
use lib $PATH_TO_THE_MODULE;
use Data::TreeDumper qw();
print "Hi\n";

让我们将您的模块简化为以下内容:

package constants;
use Exporter qw( import );
our @EXPORT_OK = qw( $PATH_TO_THE_MODULE );
our %EXPORT_TAGS = ( all => \@EXPORT_OK );
our $PATH_TO_THE_MODULE = "/path/to/site_perl";

请记住,use Foo;大致等同于BEGIN { use Foo; import Foo; },并且BEGIN块在编译后就立即执行,以下内容描述了执行脚本时发生的情况:< / p>

  1. 编译script.pl
    1. 编译use constants ':all';
    2. 执行require constants;
      1. 编译constants.pm
        1. 编译package constants;
        2. 编译use Exporter qw( import );
          1. 执行require Exporter;
            1. 编译Exporter.pm [...]
            2. 执行Exporter.pm [...]
          2. 执行import Exporter qw( import );
        3. 编译our @EXPORT_OK = qw( $PATH_TO_THE_MODULE );
        4. 编译our %EXPORT_TAGS = ( all => \@EXPORT_OK );
        5. 编译our $PATH_TO_THE_MODULE = "/path/to/site_perl";
      2. 执行constants.pm
        1. 执行our @EXPORT_OK = qw( $PATH_TO_THE_MODULE );
        2. 执行our %EXPORT_TAGS = ( all => \@EXPORT_OK );
        3. 执行our $PATH_TO_THE_MODULE = "/path/to/site_perl";
    3. 执行import constants;
    4. 编译use lib $PATH_TO_THE_MODULE;
    5. 执行require lib;
      1. 编译lib.pm [...]
      2. 执行lib.pm [...]
    6. 执行import lib $PATH_TO_MODULE;
    7. 编译use Data::TreeDumper qw();
    8. 执行require Data::TreeDumper;
      1. 编译Data/TreeDumper.pm [...]
      2. 执行Data/TreeDumper.pm [...]
    9. 编译print "Hi\n";
  2. 执行script.pl
    1. 执行print "Hi\n";

从上面,我们看到了以下情况:

  1. [1.2.1.5] $constants::PATH_TO_THE_MODULE已创建
  2. [1.2.2.3] $constants::PATH_TO_THE_MODULE设置为路径
  3. [1.3] $main::PATH_TO_THE_MODULE,创建作为别名为$constants::PATH_TO_THE_MODULE
  4. [1.6] $main::PATH_TO_THE_MODULE加到@INC
  5. [1.8] Data :: TreeDumper已加载

具有讽刺意味的是,您声称以下片段中只有一个起作用,而当两个片段基本相同时,另一个则不起作用:

use FindBin qw( $RealBin );
use lib $RealBin;

use constants qw( $PATH_TO_THE_MODULE );
use lib $PATH_TO_THE_MODULE;