Вы не хотите включать собственные модули в стандартную библиотеку расширений системного уровня.
Решение
Возможно несколько вариантов: воспользоваться параметром командной строки Perl -I; присвоить значение переменной окружения PERL5LIB; применить директиву use lib (возможно, в сочетании с модулем FindBin).
Комментарий
Массив @INC содержит список каталогов, которые просматриваются при каждс:" компиляции кода из другого файла, библиотеки или модуля командой do, require или use. Содержимое массива легко вывести из командной строки:
% perl -e 'for (@INC) { printf "%d %s\n", $i++, $_ }'
0 /usr/local/perl/lib/i686-linux/5.004
1 /usr/local/perl/lib
2 /usr/local/perl/lib/site_perl/i686-linux
3 /usr/local/perl/lib/site_perl
4 . Первые два элемента (0 и 1) массива @INC содержат обычные платформенно-за-висимый и платформенно-независимый каталоги, с которыми работают все стандартные библиотеки, модули и директивы. Этих каталогов два, поскольку некоторые модули содержат данные и
Следующая пара, элементы 2 и 3, по своим функциям аналогична элементам О и 1, но относится к конкретной системе. Допустим, у вас имеется модуль, который не поставлялся с Perl, - например, модуль, загруженный с CPAN или написанный вами. Когда вы (или, что
Последний стандартный элемент, "." (текущий рабочий каталог), используется только в процессе разработки и тестирования программ. Если модули находятся в каталоге, куда вы перешли последней командой chdir, все хорошо. Если в любом другом месте - ничего не
Иногда ни один из каталогов, указанных в @1МС, не подходит. Допустим, у вас имеются личные модули или ваша рабочая группа использует свой набор модулей, относящихся только к данному проекту. В этом случае необходимо дополнить поиск по стандартному содержи
В первом варианте решения используется флаг командной строки -1список_ка-талогов. После флага указывается список из одного или нескольких каталогов, разделенных двоеточиями'. Список вставляется в начало массива @1МС. Этот вариант удобен для простых команд
Подобную методику не следует использовать в строках #!. Во-первых, редактировать каждую программу в системе скучно. Во-вторых, в некоторых старых
операционных системах имеются ошибки, связанные с ограничением длины этой строки (обычно 32 символа, включая #!). В этом случае очень длинный путь (например, й/opt/languages/Tree/extrabits/perl) приведет к появлению таинственной ошибки "Command not found"
Нередко самое удачное решение заключается в использовании переменной окружения PERL5LIB, значение которой обычно задается в стартовом сценарии интерпретатора. Если системный администратор задаст переменную в стартовом файле системного уровня, результаты б
# Синтаксис для sh, bash, ksh и zsh $
export PERL5LIB=$HOME/perllib
# Синтаксис для csh или tcsh
% setenv PERL5LIB '/perllib
Возможно, самое удобное решение с точки зрения пользователя - включение директивы use lib в начало сценария. При этом пользователям программы вообще не придется выполнять специальных действий для ее запуска. Допустим, у нас имеется гипотетический проект S
use lib "/projects/spectre/lib"; Что делать, если точный путь к библиотеке неизвестен? Ведь проект может устанавливаться в произвольный каталог. Конечно, можно написать детально проработанную процедуру установки с динамическим обновлением сценария, но даже в этом случае путь будет же
Модуль Find Bin легко решает эту проблему. Он пытается вычислить полный путь к каталогу выполняемого сценария и присваивает его важной пакетной переменной $Bin. Обычно он применяется для поиска модулей в одном каталоге с программой или в каталоге lib
Рассмотрим пример для первого случая. Допустим, у вас имеется программа wherever/spectre/my prog, которая ищет свои модули в каталоге /wherever/spectrem, однако вы не хотите жестко фиксировать этот путь:
use FindBin;
use lib $FindBin::Bin; Второй случай - если ваша программа находится в каталоге /wherever/spectre/ bin/myprog, но ее модули должны находиться в каталоге /wherever/spectre/lib:
use FindBin qw($Bin);
use lib "$Bin/. . /lib" ; [> Смотри также -------------------------------
Документация по стандартной директиве use lib и стандартному модулю FindBin. Переменная окружения PERL5LIB описана в perl(1). Переменные окружения рассматриваются в руководстве по синтаксису командного интерпретатора.
Вы хотите подготовить модуль в стандартном формате распространения, чтобы им можно было легко поделиться с другом. Или, что еще лучше, вы собираетесь загрузить модуль на CPAN и сделать его общедоступным.
Решение
Начните со стандартной утилиты Perl h2xs. Предположим, вы хотите создать модуль Planets или Astronomy::0rbits. Введите следующие команды:
% h2xs -ХА -n Planets % h2xs -ХА -n Astronomy::0rbits Эти команды создают подкаталоги ./Planets/ и ./Astronomy/Orbits/ соответственно. В каталогах находятся все компоненты, необходимые для начала работы. Флаг -n задает имя создаваемого модуля, -X запрещает создание компонентов XS (внешних подпрограмм), а
> Смотри также ------------------------------
h2xs(1) документация по стандартным модулям Exporter, AutoLoader, Auto-Split и ExtUtils::MakeMaker. По адресу http://www.perl.com/CPAN можно ' . : я ближайший зеркальный узел и рекомендации, касающиеся предостав-лсчия модулей.
Вам хочется быстро загрузить очень большой модуль.
Решение
Воспользуйтесь модулем SelfLoader:
require Exporter:
require SelfLoader;
@ISA = qw(Exporter SelfLoader);
#
# Прочие инициализации и объявления
#
__DATA__
sub abc { .... }
sub def { .... }
Комментарий
При загрузке модуля командой require или use необходимо прочитать содержимое всего файла модуля и откомпилировать его (во внутренние деревья лексического анализа, не в байт-код или машинный код). Для очень больших модулей эта раздражающая задержка соверше
Модуль SelfLoader решает эту проблему, откладывая компиляцию каждой подпрограммы до ее фактического вызова. Использовать SelfLoader несложно: достаточно расположить подпрограммы вашего модуля под маркером __ОАТА__, чтобы они были проигнорированы компилято
В модулях, использующих SelfLoader (или AutoLoader - см. рецепт 12.10), действует одно важное ограничение. Функции, загружаемые SelfLoader или AutoLoader, не имеют доступа к лексическим переменным файла, в чьем блоке __DATA__ они находятся, поскольку
Как скажется применение SelfLoader на быстродействии программы - положительно или отрицательно? Ответ на этот вопрос зависит от количества функ-ичй в модуле, от их размера и от того, вызываются ли они на протяжении всего жизненного цикла программы или
Модуль SelfLoader не следует применять на стадии разработки и тестирова-,;|!ч модулей. Достаточно закомментировать строку __DATA__, и функции станут ггдны во время компиляции.
Смотри также -------------
Документация по стандартному модулю SelfLoader; рецепт 12.10.
Простейшее решение - воспользоваться утилитой h2xs для создания каталога и всех необходимых файлов. Предположим, у вас имеется каталог -/perllib, содержащий ваши личные библиотечные модули.
% h2xs -Xn Sample
% cd Sample
% perl Makefile.PL LIB=~/perllib
% (edit Sample.pm)
% make install
Комментарий
Модуль AutoLoader, как и SelfLoader, предназначен для ускорения работы программы. Он также генерирует функции-заглушки, которые заменяются настоящими функциями при первом вызове. Но вместо того чтобы искать все функции в одном файле под маркером __DATA__,
Процесс подготовки выглядит сложно. Вероятно, сделать это вручную действительно непросто. К счастью, h2xs оказывает громадную помощь. Помимо создания каталога с шаблонами Sample.pm и других необходимых файлов, утилита также генерирует Make-файл, который и
Как и в случае с SelfLoader, разработку и тестирование модуля лучше осуществлять без AutoLoader. Достаточно закомментировать строку __END__, пока МОДУЛ!) не придет к окончательному виду.
При работе с AutoLoader действуют те же ограничения видимости файловых лексических переменных, что и для SelfLoader, поэтому использование файловых
лексических переменных для хранения закрытой информации состояния не подойдет. Если вопрос хранения состояния становится настолько важным и труднореализуемым, подумайте о том, чтобы написать объектный модуль вместо традиционного.
> Смотри также
Документация по стандартному модулю SelfLoader; h2xs(1); рецепт 12.9.
Вы хотите заменить стандартную функцию собственной версией.
Решение
Импортируйте нужную функцию из другого модуля в свое пространство имен.
Комментарий
Многие (хотя и не все) встроенные функции Perl могут переопределяться. К этому шагу следует относиться серьезно, но в принципе это возможно. Например, необходимость в переопределении может возникнуть при работе на платформе, которая не поддерживает эмулир
Не все зарезервированные слова одинаковы. Те, что возвращают отрицательное число в функции С keyword () файла token.c исходной поставки Perl, могут переопределяться. В версии 5.004 не допускалось переопределение следующих ключевых слов:chop,defined,delete
Стандартный модуль Perl Cwd переопределяет функцию chdir. Также переопределение встречается во многих модулях с функциями, возвращающими списки: File::stat, Net::hostent, Net::netent, Net::protoent, Net::servent, Time::gmtime, Time::localtime, Time::tm, U
Переопределение осуществляется импортированием функции из другого пакета. Импортирование действует только в импортирующем пакете, а не во всех возможных пакетах. Простого переобъявления недостаточно, функцию необходимо импортировать. Это защищает от с
Предположим, вы решили заменить встроенную функцию time, которая возвращает целое количество секунд, другой, возвращающей вещественное число. Для
этого можно создать модуль FineTime с необязательным экспортированием функции time:
package FineTime;
use strict;
require Exporter;
use vars qw(@ISA @EXPORT_OK);
@ISA = qw(Exporter);
@EXPORT_OK = qw(time);
sub time() {.....} Затем пользователь, желающий использовать усовершенствованную версию time, пишет что-то вроде:
use FineTime qw(time);
$start = time();
1 while print time() - $start, "\n"; Предполагается, что в вашей системе есть функция, соответствующая приведенной выше спецификации. Некоторые решения, которые могут работать в вашей системе, рассматриваются в рецепте 12.14.
Переопределение методов и операторов рассматривается в главе 13.
> Смотри также -------------------------------
Раздел "Overriding Built-in Functions" perlsub(1)