[perl] подключение библиотеки с относительным путем.
ну можно использовать путь относительно main.pl
эээ... так, видимо мне нужно подключить мега библиотеку для определения текущего пути?
if ($0 =~ m%^(.*)/%) { unshift(@INC, $1.'/../lib'); }
else { unshift(@INC, '../lib'); }
Угу, спасибо. Я тоже понял, что истина в @INC. буду хелп читать.
use Cwd;
use File::Basename;
BEGIN {
my $dir = dirname($0);
my $path;
if ($dir =~ /^\//) {
#--absolute path
$path = $dir;
} elsif ($dir eq ".") {
#-- relative, current dir
$path = getcwd;
} else {
#-- relative, but not from current dir
$dir =~ s/^\.\///;
$path = getcwd."/$dir";
}
unshift(@INC, $path.'/LIB');
}
use FindBin; # where was script installed?
use lib $FindBin::Bin; # use that dir for libs, too
Неужели не заработало?
Объясни, пожалуйста, чо это значит. Чего там угадывается? Я не понял описание этого.
Ну плюс этот модуль может пройти все симлинки по пути, и сказать в какой директории на самом деле ты находишься. Но это так, бонусный функционал.
http://search.cpan.org/~jesse/perl-5.12.2/lib/FindBin.pm
Понял, спасибо. Почитаю.
когда ты пишешь что модуль надо искать относительно скрипта, ты как бы декларируешь что модуль "принадлежит" скрипту, что ты будешь делать когда захочешь использовать модуль из двух скриптов?
ты как бы декларируешь что модуль "принадлежит" скриптуа если так оно и есть? это вполне себе может быть специализированное cgi приложение, причем у пользователя может и не быть прав писать в /usr. Да или просто скрипт, который делает свое дело и все. То есть модуль никому больше не нужен, и /usr засорять не хочется.
Откуда такая категоричность во мнении? Я, например, подобные вещи часто практикую, и никакого плохого тона в этом не вижу.
Дело в том что
1) тестовых папок -тоже в идеале не одна.
2) хочется при написании в тессте щелкнуть коммит и только. а в проде только апдейт.
3) в идеале прод - это папка с мегаправами. куда я лезть не могу. и апдейт делает мега человек.
4) про lib::abs я чо-то ваще не понял. кажется оно не то что надо.
5) про "принадлежит" тоже не понял. Если есть скрипт main2.pl, то я так же туда подключаю эту библиотеку.
6) тут сложность также в том, что некоторый скрипт main3.pl висит в кроне и пускает main.pl UPD: которому тоже нужна эта библиотека
Вобщем как-то так.
> у пользователя может и не быть прав писать в /usr
ну это да проблема. с другой стороны не можешь писать в /usr/ положи всё в ~/usr/ или куда там можешь, и опять же пропиши это в PERL5LIB, а не в код скрипта.
в любом случае не вижу причин привязываться к положению исполняемого скрипта. это знаешь как в доисторические времена, когда под досом "программа" это был каталог с exe-шником и всеми нужными библиотеками, и это всё вместе копировалось с машины в случайные места а нынче вроде как считается правильнее когда "пакеты" и зависимости между ними. чтобы если пять программ используют один и тот же модуль, то он был бы в единственном экземпляре (это не столько вопрос занимаемого места, сколько удобства исправления ошибок в этом модуле при этом ты мог бы любое подмножество из этих 5-ти программ на конкретную машину установить.
> модуль никому больше не нужен и /usr засорять не хочется
ну там есть же namespace-ы в чем проблема? и вообще вчера не был никому нужен а сегодня стал вдруг нужен, что всё из-за этого переделывать? каждый модуль должен надеяться стать кому-нибудь нужным
если в хроне написать вызывать не просто main3.pl а PERL5LIB=/blah/ main3.pl то ему самому и всем его подпроцессам будут видны модули находящиеся в /blah/
вот ситуация: человек ведет разработку в одном месте, а на продакшн система ставится либо через какой-нить tar, либо на конечном сервере делают какой-нибудь svn/cvs checkout/update/export. В какую директорию все это попадет — непонятно.
Запускать perl с ключами или выставлять ENV там может не получится по разным причинам.
Так что вполне нормальное решение, оценить кривость или прямость можно только зная конкретику, а ее мы не знаем. Конкретно я, даже и не хочу знать
> Так в ссылке же было решение на две строчки:
> Неужели не заработало?
только там надо
use lib "$FindBin::Bin/LIB";
#/usr/bin/perl -w
BEGIN
{
push @INC, "./blib/arch", "./blib/lib";
}
etc...
2)
#!/usr/bin/perl -w
use strict;
use Glib;
use Gtk2 -init;
use blib; ########################### вот так выызывать
use Pixels;
etc...
где Pixels это самописная библиотека, вобщем см perldoc blib
а FindBin заточен на работу на винде, чтобы скрипт без изменений работал и на юнихах и на винде
ну use lib './LIB'; - тоже не помогает.use lib 'тут надо писать абсолютный путь от корня';
эээ... так, видимо мне нужно подключить мега библиотеку для определения текущего пути?
а у тебя указан относительный путь, потому и не работает... это ситуация когда нет рутовых прав и все модули лежат в домашней директории и чтобы это обойти существует blib
можно еще require lib делать
@INC The array @INC contains the list of places that the "do EXPR",
"require", or "use" constructs look for their library files.
It initially consists of the arguments to any -I command-line
switches, followed by the default Perl library, probably
/usr/local/lib/perl, followed by ".", to represent the current
directory. ("." will not be appended if taint checks are
enabled, either by "-T" or by "-t".) If you need to modify
this at runtime, you should use the "use lib" pragma to get the
machine-dependent library properly loaded also:
use lib '/mypath/libdir/';
use SomeMod;
You can also insert hooks into the file inclusion system by
putting Perl code directly into @INC. Those hooks may be sub-
routine references, array references or blessed objects. See
"require" in perlfunc for details.
@_ Within a subroutine the array @_ contains the parameters passed
to that subroutine. See perlsub.
%INC The hash %INC contains entries for each filename included via
the "do", "require", or "use" operators. The key is the file-
name you specified (with module names converted to pathnames
and the value is the location of the file found. The "require"
operator uses this hash to determine whether a particular file
has already been included.
If the file was loaded via a hook (e.g. a subroutine reference,
see "require" in perlfunc for a description of these hooks
this hook is by default inserted into %INC in place of a file-
name. Note, however, that the hook may have set the %INC entry
by itself to provide some more specific info.
push @INC, "./blib/arch", "./blib/lib";Сказали же, что нужен путь относительно скрипта, а не относительно cwd!
Сказали же, что нужен путь относительно скрипта, а не относительно cwd!не зная положение скрипта путь к библиотеке относительно скрипта вычислить невозможно , если не дает возможность ставить модули провайдер как системные - значит надо все прописывать, иначе работать не будет. вот хоть ты тресни
не зная положение скрипта путь к библиотеке относительно скрипта вычислить невозможноНе зная положение скрипта его и запустить нельзя будет.
Всем спасиба.
Оставить комментарий
Teteshnik
Ситуация обычная. Есть тестовые и боевые библиотеки и скрипты. Отличаются они только конфиг файлом. Соответственно. Все кроме конфиг файла лежит в СВН.Структура такая
/home/tagan/test/main.pl
/home/tagan/test/LIB/lib1.pm
/home/tagan/test/LIB/lib2.pm
/home/tagan/test/LIB/config.pm
я в файле main хочу подключить LIB.
Делаю use lib 'LIB';.
И теперь получается
/home/tagan/test# ./main.pl - все работает
/home/tagan# ./test/main.pl - ничо не работает
Меня интересует как подключить LIB, без указания абсолютного пути и чтобы работал 2-й вариант.