所以,我试图导入模块到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
,它会编译并如预期打印路径。
你要求你的代码不能正常工作,这是因为$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
块,尽快为他们被编译执行一致,以下描述了当你执行这个脚本会发生什么:
script.pl
编译use constants ':all';
执行require constants;
编译constants.pm
编译package constants;
编译use Exporter qw( import );
执行require Exporter;
编译Exporter.pm
[...]
执行Exporter.pm
[...]
执行import 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";
执行constants.pm
执行our @EXPORT_OK = qw( $PATH_TO_THE_MODULE );
执行our %EXPORT_TAGS = ( all => \@EXPORT_OK );
执行our $PATH_TO_THE_MODULE = "/path/to/site_perl";
执行import constants;
编译use lib $PATH_TO_THE_MODULE;
执行require lib;
编译lib.pm
[...]
执行lib.pm
[...]
执行import lib $PATH_TO_MODULE;
编译use Data::TreeDumper qw();
执行require Data::TreeDumper;
编译Data/TreeDumper.pm
[...]
执行Data/TreeDumper.pm
[...]
编译print "Hi\n";
script.pl
执行print "Hi\n";
从上面,我们可以看到以下情况发生:
$constants::PATH_TO_THE_MODULE
$constants::PATH_TO_THE_MODULE
被设定为路径$main::PATH_TO_THE_MODULE
创建为别名$constants::PATH_TO_THE_MODULE
$main::PATH_TO_THE_MODULE
加到@INC
讽刺的是,你声称只有以下摘录的工作之一,而另一个没有时,他们基本上是相同的:
use FindBin qw( $RealBin );
use lib $RealBin;
use constants qw( $PATH_TO_THE_MODULE );
use lib $PATH_TO_THE_MODULE;