我有一个名为foo
的目录,其中我有lib
和bin
。 bin
中的脚本需要lib
中的内容。我做这样的事情:
#!perl
use strict;
use warnings;
use lib '../lib';
use Foo; # <-- comes from lib
但这意味着我必须在bin
目录中运行脚本。当然有更好的方法。什么是正确的方法?
答案 0 :(得分:48)
答案 1 :(得分:5)
通过.pl
解析__FILE__
的完整路径,并在最后添加../lib
或弹出split(/\//,__FILE__)
的最后一个元素并添加{{1}那个。
答案 2 :(得分:3)
“FindBin”模块仅在perl脚本所在的目录位于系统PATH中时才有效,否则将失败。要克服,您可以操纵$0
值来获取路径到perl模块的信息,并将值传递给use lib
。
像这样 -
BEGIN {
use File::Spec::Functions qw(rel2abs);
use File::Basename qw(dirname);
#Covert the script path to absolute and get its directory name
our $path = dirname( rel2abs($0) );
#Replace the bin tag with lib to get module directory
$path =~ s{bin/?$}{lib};
}
use lib $path;
修改强> FindBin模块工作得非常完美,可以按Michael's answer中的描述使用。我对其工作原理的理解是不完整的,因此我引发了我现在撤回的第一条评论。无论如何,我没有看到任何理由为什么这个方法不应该工作,尽管比使用FindBin(TMTOWTDI)可以实现的更多行。
答案 3 :(得分:3)
我通常使用这种技术。令人遗憾的是,我的PHP日子受到了启发:
在您知道给定文件将相对于当前文件的位置,并且不确定可能在调用时调用它或周围环境的入口点的情况下,它非常方便。
但是,我通常会将此技术仅用于需要虚拟库来模拟事物的测试脚本。
use File::Basename ();
use Cwd ();
my $base_dir;
my $relative_path;
BEGIN {
$realitive_path = '../../' # Path to base of project relative to the current file
$base_dir = Cwd::realpath( File::Basename::dirname(__FILE__) .'/' . $relative_path );
}
use lib "${base_dir}/lib";
use Foo;
理想情况下应该有某个模块可以执行此操作,如果没有,我很想写一个:
use Some::Module ();
use lib Some::Module::relative_self('../../lib', __FILE__ );
答案 4 :(得分:1)
use lib './';
在Linux机器上使用Perl v5.14.2为我工作,将文件包含在与我的脚本相同的目录中。
也许你可以在你的脚本工作目录下移动你的lib和bin目录并尝试使用
引用它们。use lib './bin/';
答案 5 :(得分:0)
我的解决方案:
use lib substr(__FILE__, 0, rindex (__FILE__, "/"));
答案 6 :(得分:0)
只是将我自己的两分钱加到这个答案集中,我通常会使用以下内容来解决这个问题:
use lib do {
use Cwd 'realpath';
my ($dir) = __FILE__ =~ m{^(.*)/}; # $dir = path of current file
realpath("$dir/../lib"); # path of '../lib' relative to $dir
};
我喜欢使用do
块,因为所需的一切都整齐地包含在其中。如果您需要复制/粘贴,或者稍后尝试理解您的代码,则无需查找单独的BEGIN
块或类似内容。
上面的代码天真地假设/
用作目录/文件名分隔符。
答案 7 :(得分:-3)
怎么样:
BEGIN: {
push @INC, '/full/path/to/lib';
}
要做一个相对引用会假设你要将它保存在bin目录中,所以改为在那里插入相对引用。