Механизм Модуля Perl

На этой странице описывается механизм создания, компиляции, тестирования, выпуска и обслуживания модулей Perl.

Это не справочное руководство. Скорее, это текущий отчет о том, как делать эти вещи. Более того, это отчет о том, как я делаю эти вещи. Соответственно

 

  • он игнорирует XS
  • пути и другие сведения могут отличаться в вашей системе
  • вы должны смириться с определенным количеством редактирования

 

  • Модули Perl
    • CPAN
    • Имена модулей
    • Один компонент, два компонента, три компонента, четыре …
    • Имена модуля против Наследования
    • Файлы модуля
    • Библиотеки модуля
  • Ready, Set, Go
    • Разработка каталогов
    • Как трудно это может быть?
    • h2xs
  • Создание модуля Perl
    • MANIFEST
    • README
    • Изменения
    • t/Foo-Bar.t
    • Makefile.PL
    • Bar.pm
  • Сборка Модуля Perl
    • perl Makefile.PL
    • make
    • тест make
    • установка make
    • make dist
    • pm_to_blib
  • Установка в нестандартных местах
    • Где-нибудь еще
    • PERL5LIB
  • Сборка Perl Связанных Модулей
  • Тестирование модуля Perl из Build Directory
    • Написание тестов
    • Дата файлы
    • Подробный вывод
    • Выбор тестов
  • Тестирование модуля из программы Perl
  • Документирование Модуля Perl
    • Man Страницы

Модули Perl

Модуль Perl – это автономный фрагмент кода Perl, который может использоваться программой Perl или другими модулями Perl. Концептуально он похож на библиотеку ссылок C или C++ класс.

CPAN

Комплексная Сеть Архивов Perl (CPAN) содержит огромную коллекцию общедоступных модулей и содержит рекомендации по созданию и использованию модулей. Этот документ содержит введение и обзор; CPAN следует консультироваться для деталей и ссылок.

Имена модулей

Каждый модуль Perl имеет имя. Имена модулей должны быть уникальными. Чтобы минимизировать конфликты пространств имен, Perl предоставляет иерархическое пространство имен для модулей, аналогичное пространству имен для классов Java.

Компоненты имени модуля разделяются двойными двоеточиями (::). Таким образом, мы можем иметь без конфликта.

Module Function
Math::Complex Complex number data type
Math::Approx Approximate x,y-values by a function
String::Approx Approximate string matching and substitution
String::BitCount Count number of “1” bits in strings

 

Один компонент, два компонента, три компонента, четыре …

Нет ограничений на количество компонентов в имени модуля; однако большинство обычных прикладных модулей имеют двухкомпонентные имена.

Однокомпонентные имена модулей являются ограниченным ресурсом и должны использоваться только для явно глобальных вещей:

 

Module Function
Config Stores details of the Perl build configuration

 

Имена с тремя или более компонентами могут запутать пользователей:

 

Настоящий модуль, пожалуйста, встаньте?

 

  • Математика::Комплекс::Номер
  • Математика:: Номер::Комплекс

Имена модуля против Наследования

Иерархия имен модулей не имеет ничего общего с наследованием классов. Математика::Комплекс может быть подклассом Математики, а может и нет. В этом отношении это может быть подклассом String::Approx.

Файлы модуля

Каждый модуль содержится в одном файле. Файлы модуля хранятся в иерархии подкаталогов, которая параллельна иерархии имен модулей. Таким образом,

 

Module Is Stored In
Config Config.pm
Math::Complex Math/Complex.pm
String::Approx String/Approx.pm

 

Все файлы модулей имеют расширение .pm. pm обозначает Perl Module.

 

Вы также можете столкнуться с файлами .pl. pl обозначает Perl Library. Файлы .pl использовались в Perl4; Файлы .pm предпочтительнее в Perl5.

 

Библиотеки модуля

У интерпретатора Perl есть список каталогов, в которых он ищет модули. В Perl программе этот список доступен в глобальном массиве @INC. INC это сокращение от «include».

Чтобы увидеть начальное содержимое @INC, сделайте

 

>perl -V
 ...
@INC: 
/usr/local/lib/perl5/5.8.6/i686-linux
/usr/local/lib/perl5/5.8.6
/usr/local/lib/perl5/site_perl/5.8.6/i686-linux
/usr/local/lib/perl5/site_perl/5.8.6
/usr/local/lib/perl5/site_perl/5.8.5/i686-linux
/usr/local/lib/perl5/site_perl/5.8.5
/usr/local/lib/perl5/site_perl
.

 

Как установлено на моей машине, интерпретатор Perl ищет модули в восьми местах. Три из них имеют на своем пути i686-linux; они предназначены для модулей, которые ссылаются на отдельно скомпилированный код C, и поэтому зависят от архитектуры. Последний является текущим рабочим каталогом.

/usr/local/lib/perl5/5.8.6 содержит модули, которые поставляются со стандартным дистрибутивом Perl5. /usr/local/lib/perl5/5.8.5 содержит модули из предыдущей версии Perl. Модули из последовательных дистрибутивов хранятся в разных каталогах для поддержки программ, которые могут использовать более старые версии.

 

Наконец, /usr/local/lib/perl5/site_perl/ содержит модули, которые создаются и устанавливаются локально; то есть не являются частью стандартного дистрибутива. Локальные и стандартные модули разделяются таким образом, что новая версия интерпретатора может заменить стандартные модули, не нарушая локально установленные.

 

Итак, если перечисленные выше модули были установлены в моей системе, они будут в

 

Module Path
Config /usr/local/lib/perl5/site_perl/5.8.6/Config.pm
Math::Complex /usr/local/lib/perl5/site_perl/5.8.6/Math/Complex.pm
String::Approx /usr/local/lib/perl5/site_perl/5.8.6/String/Approx.pm

 

Ready, Set, Go

Perl является интерпретируемым языком и не имеет различий между исходным кодом и объектным кодом, которые существуют в таких языках, как C или Java. Программист пишет файл .pm, а интерпретатор выполняет его. Это означает, что вы можете редактировать файлы .pm в /usr/local/lib/perl5/site_perl/, и ваши изменения вступят в силу немедленно.

Нет.

 

Многие люди могут запускать программы, которые зависят от модулей в /usr/local/lib/perl5/site_perl. Когда модули ломаются, программы ломаются, и тогда у вашей двери выстраиваются пользователи.

 

Разработка каталогов

Вам необходимо создать область разработки для разработки модулей Perl. Это может быть в /usr/local/src, это может быть в вашем домашнем каталоге или где-то еще. Это не должно быть в /usr/local/lib/perl5/site_perl/.

Я напишу …/development/ для ссылки на каталог разработки, где бы он ни находился.

 

Как трудно это может быть?

Сборка и установка модулей Perl кажутся простыми. Они не скомпилированы и не связаны. Все, что вам нужно сделать, это скопировать файл .pm из области разработки в /usr/local/lib/perl5.

Для обычных модулей Perl это действительно так. Тем не мение. Некоторые модули Perl связываются с динамически загружаемыми общими библиотеками C через специальный язык интерфейса, называемый XS. Это не только требует компиляции и компоновки, но потенциально включает в себя все наихудшие виды системных зависимостей.

 

h2xs

Чтобы начать работу в этом опасном путешествии, Perl предлагает утилиту h2xs. h2xs читает файл .h для библиотеки C и создает каркас для файла .xs, который потребуется для создания модуля Perl, который ссылается на эту библиотеку. Он также создает довольно сложную систему каталогов и make файлов для сборки и тестирования модуля Perl.

Со временем структура, которую создает h2xs, стала стандартом для создания модулей Perl – даже модулей, которые не связаны с C-кодом. Я использую эту структуру, потому что

 

  • оно работает
  • Мне нравится быть стандартным

Создание модуля Perl

Чтобы создать новый модуль Perl, перейдите в область разработки и выполните

 

.../development>h2xs -X -n Foo::Bar
Writing Foo-Bar/lib/Foo/Bar.pm
Writing Foo-Bar/Makefile.PL
Writing Foo-Bar/README
Writing Foo-Bar/t/Foo-Bar.t
Writing Foo-Bar/Changes
Writing Foo-Bar/MANIFEST
.../development>

 

Ключ -X указывает, что этот модуль не связан с кодом C. Ключ -N задает имя нового модуля.

h2xs создает Foo-Bar/ и заполняет его шестью перечисленными файлами. Foo-Bar/ называется каталогом модуля или каталогом сборки.

 

Давайте посмотрим на шесть файлов.

 

MANIFEST

MANIFEST перечисляет файлы в каталоге сборки. MakeMaker проверяет наличие всех файлов, перечисленных в MANIFEST, и выдает жалобу, если их нет. Это в основном используется, чтобы гарантировать, что распределения модуля получены неповрежденными.

README

README содержит скелет для файла README. Создание файла README необязательно, но считается хорошей практикой. Модули, загруженные в CPAN, должны иметь файлы README.

Файл README также содержит этот шаблон

 

Copyright (C) 2005 your name here

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.6 or,
at your option, any later version of Perl 5 you may have available.

 

Perl распространяется в соответствии с условиями GPL и Artistic License; если это не те термины, которые вам нужны для вашего модуля, вам нужно изменить этот язык.

Изменения

Это файл для записи истории изменений модуля. h2xs создает его, но программист должен его поддерживать.

t/Foo-Bar.t

t/ является подкаталогом для тестовых файлов, а t/Foo-Bar.t содержит скелетную процедуру тестирования для модуля. После создания все, что он делает, это проверяет, что модуль может быть загружен в программу Perl. Если ничего другого, это отлавливает синтаксические ошибки в модуле. Программистам рекомендуется создавать функциональные тесты для своих модулей.

Makefile.PL

Один makefile не может решить все проблемы конфигурации системы, связанные с созданием модуля Perl XS. Вместо того, чтобы пытаться, h2xs создает Makefile.PL. Makefile.PL. содержит короткую программу Perl:

 

.../development/Foo-Bar>cat Makefile.PL
use 5.008006;
use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
    NAME              => 'Foo::Bar',
    VERSION_FROM      => 'lib/Foo/Bar.pm', # finds $VERSION
    PREREQ_PM         => {}, # e.g., Module::Name => 1.1
    ($] >= 5.005 ?     ## Add these new keywords supported since 5.005
      (ABSTRACT_FROM  => 'lib/Foo/Bar.pm', # retrieve abstract from module
       AUTHOR         => 'your name <your email address>') : ()),
);

 

Решающая линия-вторая: use ExtUtils::MakeMaker;. MakeMaker является точкой входа в большую систему модулей Perl. Эти модули знают, как писать makefile, а их различные подклассы знают, как писать makefile для вашей конкретной системы. Вызов WriteMakefile() приводит к записи соответствующего makefile. Аргументы в WriteMakefile() управляют содержимым makefile.

lib/Foo/Bar.pm

Это фактический модуль Perl. Он помещается в дерево подкаталогов, которое отображает имя модуля, так же, как и при установке. Если вы добавите больше модулей в этот каталог сборки, вы должны поместить их в соответствующие пути в lib/.

В созданном виде Bar.pm содержит скелетный код и документацию; см. Анатомию Модуля для описания этого.

 

N.B. Bar.pm создается с тем же уведомлением об авторских правах, что и README.

 

Сборка Модуля Perl

Чтобы построить модуль Perl, вы должны выполнить четыре команды из каталога модулей:

 

perl Makefile.PL
make
make test
make install

 

perl Makefile.PL

Первым шагом является запуск Makefile.PL для создания makefile. Makefile.PL – это Perl программа, но в ней нет #! строка, поэтому вы должны вызывать интерпретатор явно.

make

Это создаст каталог с именем blib (для Build LIB) в каталоге модуля и установит в него модуль. blib является частной тестовой областью для модуля. Попробуй сделать

 

.../development/Foo-Bar>ls -R blib/

 

Довольно удивительно, нет? Если Foo::Bar связан с кодом C, вы увидите, что эти подкаталоги заполнены .ix файлами, .al файлами, .bs файлами и .so файлами и, возможно, грифоном или двумя. Копия вашего .pm файла тоже там:

 

.../development/Foo-Bar/blib/lib/Foo/Bar.pm

 

тест make

Он запускает t/Foo-Bar.t со специальными переключателями командной строки, которые заставляют Perl находить копию вашего модуля, которая похоронена в blib/, а не любые другие копии, которые могут колебаться вокруг. Здесь вы увидите помеченные синтаксические ошибки и функциональные ошибки, если добавите свои собственные тесты.

установка make

Это установит ваш модуль в /usr/local/lib/perl5/site_perl. В системах Unix для этого обычно требуется root доступ. Как только он установлен, он доступен всем в вашей системе.

make dist

Если вы хотите поделиться своим модулем с пользователями в других системах, сделайте

 

.../development/Foo-Bar>make dist

 

Это находит все файлы, перечисленные в MANIFEST, tar и сжимает их, и записывает архив (например) в каталог разработки. Этот архив является полным дистрибутивом вашего модуля. Вы можете дать его любому, и он может собрать и установить ваш модуль в своей системе.

 

Foo-Bar-1.00.tar.gz

 

pm_to_blib

Все хорошие makefile сравнивают время модификации исходных и объектных файлов и восстанавливают только устаревшие. Отслеживание времени модификации всех файлов в blib/ было бы сложным, поэтому makefile создает файл нулевой длины с именем pm_to_blib в каталоге модуля и отслеживает время его изменения.

Если pm_to_blib не синхронизируется с вашими файлами .pm, то makefile будет считать, что blib/ обновлен, и не будет его перестраивать. Если это произойдет, просто удалите pm_to_blib и снова запустите make.

 

Установка в нестандартных местах

Во многих системах /usr/local/lib/perl5/site_perl принадлежит пользователю root с разрешениями 0755. Это означает, что вы должны использовать su для получения прав, чтобы установить туда модуль. Если у вас нет root в вашей системе, вы можете

  • попросите системного администратора установить модуль для вас
  • установить модуль в другом месте

Где-нибудь еще

Вот как установить модуль Perl в нестандартном месте.

Сначала выберите каталог для хранения ваших модулей Perl и скриптов. Строго не важно, где находится каталог, но он должен быть где-то

 

  • у вас есть доступ для записи
  • не уйдет

Ваш домашний каталог, вероятно, хороший выбор; /usr/tmp, вероятно, нет. Мы напишем для вашего домашнего каталога.

 

/home/uid

 

Затем вернитесь в каталог разработки и введите

 

.../development/Foo-Bar>perl Makefile.PL INSTALL_BASE=/home/uid
.../development/Foo-Bar>make install

 

Это соберет модуль и установит его в ваш личный каталог следующим образом:

 

/home/uid/lib/perl5/     # modules
/home/uid/bin/           # scripts
/home/uid/man/           # man pages

 

PERL5LIB

Perl не знает, чтобы искать модули в вашем личном каталоге; вы должны сказать это. Есть несколько способов сделать это. Возможно, наиболее подходящим в этом контексте является установка переменной среды PERL5LIB. В оболочках Bourne запустите, и Perl добавит ваш каталог в начало @INC.

 

export PERL5LIB=/home/uid/lib/perl5

 

Сборка Perl Связанных Модулей

Иногда у вас есть несколько модулей, которые работают вместе. Вы можете создать отдельный каталог модулей для каждого:

 

.../development>h2xs -X -n Foo::Bar
.../development>h2xs -X -n Foo::Zot

 

Одна из проблем заключается в том, что вы должны постоянно переключаться между каталогами, чтобы редактировать и создавать их. Большая проблема в том, что вы не можете проверить их вместе.

Предположим, вы вносите изменения в оба модуля. Теперь вы пытаетесь проверить Foo::Bar. Foo::Bar использует Foo::Zot. В частности, он использует текущую версию, в которой нет правок, которые вы только что внесли в Foo::Zot в области разработки. Таким образом, вы не можете протестировать Foo::Bar, пока не установите новую версию Foo::Zot, которую вы, вероятно, не хотите делать прямо сейчас, поскольку вы еще не тестировали ее.

 

Решение состоит в том, чтобы создать оба модуля в одном каталоге:

 

.../development>h2xs -X -n Foo::Bar
.../development>cp Foo-Bar/lib/Foo/Bar.pm Foo-Bar/lib/Foo/Zot.pm

 

Вам даже не придется возиться с Makefile.PL чтобы сделать это; MakeMaker сканирует каталог сборки для файлов .pm и включает их все в makefile.

 

Тестирование модуля Perl из Build Directory

 

.../development/Foo-Bar>make test

 

тестирует ваш модуль, запустив тестовые файлы в t/. h2xs создает для вас t/Foo-Bar.t, но вы можете иметь столько файлов .t, сколько захотите. Например, если вы поддерживаете несколько файлов .pm в одной директории модуля, каждый из них может иметь свой собственный файл .t:

 

Foo-Bar/t/Foo-Bar.t
Foo-Bar/t/Foo-Zot.t

 

Тестовые файлы запускаются в алфавитном порядке, поэтому, если вы хотите контролировать порядок выполнения, вы можете дать им такие имена, как

 

Foo/Bar/t/1_basic.t
Foo/Bar/t/2_advanced.t

 

Написание тестов

make test использует Test::Harness для запуска тестовых файлов. Тестовые файлы печатают свои результаты на STDOUT. Test::Harness собирает выходные данные и сообщает количество пройденных и неудачных тестов.

В документации TAP (Test Anything Protocol) подробно описывается формат вывода, ожидаемый от тестовых файлов. Однако, чтобы начать, вам нужно знать только несколько вещей

 

  • Первая строка вывода должна быть

 

1..N

 

где N – общее количество тестов в файле. Скелет, представленный в Foo-Bar.t, имеет код для печати этой строки.

  • Каждый тест должен распечатать

 

ok n description

 

в случае успеха или

 

not ok n description

 

на провал. n – номер теста; они увеличиваются от 1 до N при выполнении тестов. Описание не является обязательным; это может быть любой текст.

  • Все, что напечатано в STDERR, отображается на экране и в противном случае игнорируется.

Модули Test::Simple и Test::More предоставляют дополнительные возможности для написания тестов. Я люблю ставить

 

my $N = 1;
sub Not { print "not " }
sub OK  { print "ok ", $N++, "\n" }

 

вверху моих .t файлов. Тогда я могу написать тестовый код, как

 

$actual eq $expected or Not; OK;

 

Дата файлы

Если модуль читает или пишет файлы, вы хотели бы иметь возможность проверить эту функциональность. t/ это удобное место для размещения файлов данных для использования в тестовых процедурах:

 

.../development/Foo-Bar/t/Foo-Bar.t
.../development/Foo-Bar/t/fodder

 

make test будет запускать Foo-Bar.t как обычно; он будет игнорировать фураж, потому что этот файл не имеет расширения .t. Foo-Bar.t может затем проверить Foo::Bar на файле фуража.

Помните, что когда make тест выполняет файл .t, текущим рабочим каталогом является каталог модуля, а не t/. Так

 

open FILE, "fodder"

 

не сработает. Вместо этого вы должны написать

 

open FILE, "t/fodder"

 

Подробный вывод

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

 

make TEST_VERBOSE=1 test

 

Это выведет STDOUT из тестовых файлов на ваш экран. Некоторый хорошо подобранный текст описания в результатах теста сделает это более информативным.

Выбор тестов

По умолчанию make тест запускает все файлы .t в каталоге t. Если вас интересует только один тестовый файл, вы можете запустить его с

 

make TEST_FILES=t/Foo-Bar.t test

 

Переключатели для проведения теста можно комбинировать. Чтобы увидеть вывод из одного тестового файла, выполните

 

make TEST_FILES=t/Foo-Bar.t TEST_VERBOSE=1 test

 

Тестирование модуля из программы Perl

Иногда вы хотите протестировать модуль, запустив программу, которая фактически его использует. Если модуль установлен, это достаточно просто, но что, если модуль не установлен? Каким-то образом вы должны получить программу, чтобы найти файл .pm в каталоге модуля.

Раньше требовалось играть в сложные игры с @INC или использовать lib, но в Perl 5.004 есть лучший способ: blib. blib – это (что еще?) модуль Perl. Если вы находитесь в каталоге модуля, вы можете сделать

 

.../development/Foo-Bar>perl -Mblib program.pl

 

предоставить program.pl доступ к Foo::Bar. Если вы находитесь где-то еще, укажите путь к каталогу модуля в качестве аргумента для blib

 

somewhere/else>perl -Mblib=.../development/Foo-Bar program.pl

 

Документирование Модуля Perl

Модули Perl содержат собственную документацию, написанную на простом языке разметки, который называется Plain Old Documentation (POD). Существует множество фильтров для перевода файлов POD в другие форматы: pod2text, pod2man, pod2html, pod2latex, pod2usage.

Программистам настоятельно рекомендуется писать POD для всех своих программ и модулей Perl. См. POD модуля для деталей.

 

Man Страницы

Man страницы для модулей Perl хранятся в man/man3/.

Процедура сборки для модуля Perl автоматически создает и устанавливает man-страницу для модуля. make вызывает pod2man для генерации Foo::Bar.3 из Bar.pm, и make установит копии Foo::Bar.3 в каталог man3.

 

Заметки

уникальный

Строго говоря, имена модулей должны быть уникальными только в каждой установке интерпретатора Perl. Однако авторам модулей настоятельно рекомендуется выбирать глобально уникальные имена для своих модулей.

Единственный

Модули XS и autosplit содержат несколько файлов.

INC

Возможно, это было бы лучше назвать @LIB, но … хм … это не так.

текущий рабочий каталог

Это менее полезно, чем кажется, потому что вы обычно не находитесь в каталоге, где хранится модуль.

пользователи выстроились у вашей двери

Я говорю из личного опыта здесь.

XS

XS – это (фонетическая?) Аббревиатура для внешней подпрограммы. «Внешний» означает внешний для Perl, т. е. написанный на C. Для получения дополнительной информации о XS, см. Механику XS.

плавание вокруг

скажем, в /usr/local/lib/perl5/site_perl/

не синхронизировано

скажем, потому что вы коснулись его, или из-за задержки NFS

возиться с Makefile.PL

MakeMaker является большим и сложным, и makefiles, которые он генерирует, непостижимы. Будьте внимательны.

 

Оригинальная статья: http://world.std.com/~swmcd/steven/perl/module_mechanics.html