Как использовать модуль Perl из относительного местоположения? - PullRequest
36 голосов
/ 25 апреля 2009

У меня есть каталог под названием foo, и в этом у меня есть lib и bin. Скриптам в bin нужны вещи в lib. Я делаю что-то вроде этого:

#!perl
use strict;
use warnings;
use lib '../lib';
use Foo; # <-- comes from lib

Но это означает, что я должен быть в bin директории, чтобы запустить скрипт. Конечно, есть лучший способ. Какой правильный способ сделать это?

Ответы [ 8 ]

48 голосов
/ 25 апреля 2009

Стандартный FindBin модуль делает то, что вы хотите.

use FindBin;
use lib "$FindBin::Bin/../lib";

perldoc FindBin для более.

5 голосов
/ 25 апреля 2009

Изучите полный путь к вашему .pl через __FILE__ и, наберите ../lib в конце или вытолкните последний элемент split(/\//,__FILE__) и добавьте к нему /lib

3 голосов
/ 25 апреля 2009

Я обычно использую эту технику. Его печально вдохновили мои дни 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__ ); 
3 голосов
/ 25 апреля 2009

Модуль «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;

EDIT: Модуль FindBin работает просто отлично и может использоваться, как описано в Michael's answer . Мое понимание его работы было неполным и поэтому заставило меня сделать первый комментарий, от которого я сейчас отказываюсь. В любом случае, я не вижу причин, по которым этот метод не должен работать, хотя с несколькими строками больше, чем можно было бы получить с помощью FindBin (TMTOWTDI).

1 голос
/ 15 ноября 2017
use lib './';

работал для меня с Perl v5.14.2 на коробке linux, чтобы включить файлы в тот же каталог, что и мой скрипт.

Возможно, вам будет полезно переместить каталоги lib и bin в рабочий каталог вашего скрипта и попытаться сослаться на них, используя

use lib './bin/';
0 голосов
/ 28 сентября 2013

Просто чтобы добавить свои два цента к этой коллекции ответов, я обычно решаю эту проблему, используя что-то вроде:

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 или что-то в этом роде.

Приведенный выше код наивно предполагает, что / используется в качестве разделителя dir / filename.

0 голосов
/ 17 апреля 2012

Мое решение:

use lib substr(__FILE__, 0, rindex (__FILE__, "/"));
0 голосов
/ 25 апреля 2009

Как насчет:

BEGIN: {
    push @INC, '/full/path/to/lib';
}

Для создания относительной ссылки предполагается, что вы сохраните ее в каталоге bin, поэтому вместо нее вставьте относительную ссылку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...