Чтение онлайн

на главную - закладки

Жанры

Язык программирования Perl

Шохирев Михаил Васильевич

Шрифт:

perldoc perlsub

Лекция 13. Библиотеки, пакеты и модули

В этой лекции рассмотрена модульная организация программ на Perl. Знать ее совершенно необходимо, поскольку типичные программы сами размещаются в нескольких исходных файлах и не обходятся без подключения внешних библиотечных модулей. Правила организации программных единиц и приемы работы с пространствами имен и составляют тему обсуждения в этой лекции.

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

Современные языки программирования

предоставляют программистам средства для того, чтобы упорядочить свои наработки. Нетривиальная программа обычно представляет из себя некоторое количество файлов с исходными текстами, расположенных в нескольких каталогах. А большие программные комплексы образуют внушительную иерархию подкаталогов, содержащих десятки и сотни программных файлов. Универсальные подпрограммы принято сохранять в отдельных библиотечных файлах, чтобы обращаться к ним из разных программ. Сходные по назначению процедуры и функции объединяются в библиотеки подпрограмм. Библиотека программ на Perl - это файл, обычно с суффиксом .pl, где хранится произвольный набор подпрограмм для использования в других программах. (Этот суффикс иногда применяется для прикладных программ на Perl, но для них рекомендуется использовать суффикс .plx.) Для примера напишем небольшую программную библиотеку для работы с данными о музыкальных дисках и сохраним ее в файле 'lib/music_lib.pl':

# библиотека подпрограмм 'music_lib.pl'

sub albums_by_artist { # найти альбомы указанного артиста

my ($artist) = @_; # аргумент поиска: артист

my @albums = ; # возвращаемый список

seek DATA, 0, 0; # ищем с начала файла

while (<DATA>) { # просматриваем альбомы в файле

push @albums, $1 if /$artist;(.+?);/; # и выбираем

} # все подходящие

return @albums; # результат: список альбомов

}

# ... другие подпрограммы библиотеки...

__DATA__ # конец библиотечного файла

Рассмотрим, как происходит обращение к библиотечным подпрограммам во время выполнения программы.

Чтобы воспользоваться подпрограммой из библиотечного файла, нужно в вызывающей программе загрузить библиотеку командой do 'file.pl'. Команда do загружает любую Perl-программу из внешнего файла во время выполнения программы. Причем в библиотеке в свою очередь могут загружаться программные файлы по команде do. Кроме этого, do регистрирует загруженные программы в специальном хэше %INC. Если do не может найти или прочитать файл, она возвращает неопределенное значение undef и присваивает специальной переменной $! признак ошибки. Если do прочитала файл, но не может его скомпилировать, она возвращает undef и помещает сообщение об ошибке в специальную переменную .$@. Если файл успешно скомпилирован, do возвращает значение последнего вычисленного выражения.

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

do 'lib/music_lib.pl'; # загрузить библиотеку

# вызвать библиотечную подпрограмму

my @albums = albums_by_artist('Elton John');

print "$_\n" foreach(@albums); # напечатать найденный список

Обратите внимание, что в нашем примере явно указан путь к подкаталогу с библиотекой, что предполагает запуск программы из определенного каталога. Гораздо лучше сделать так, чтобы расположение библиотек не зависело от местонахождения вызывающей программы. Для этого в Perl имеется специальный массив @INC,

в котором хранится список каталогов для поиска загружаемых исходных файлов. В этот массив по умолчанию включаются каталоги, где находятся системные библиотеки Perl. Чтобы на время выполнения программы добавить в этот список свои каталоги с библиотеками, можно воспользоваться опцией – I, указываемой в командной строке при запуске компилятора perl. Например, запустим на выполнение программу и укажем дополнительно искать файлы в каталоге /Shock/Mike/lib и его подкаталогах:

perl -I/Shock/Mike/lib program.pl

Тогда в программе можно указывать путь к библиотекам относительно одного из перечисленных в массиве @INC каталогов:

do 'music_lib.pl'; # искать библиотеку в списке @INC

Другой способ добавить в массив @INC каталог для поиска загружаемых файлов - использовать директиву (прагму) use lib. Для этого в программе перед командой загрузки библиотеки нужно указать ее расположение, например так:

use lib('/Shock/Mike/lib'); # добавить путь к списку @INC

Команда загрузки внешних программ do считается устаревшей и употребляется все реже и реже. Вместо нее применяется команда require, имеющая целый ряд преимуществ. Эта команда вызывает ошибку, если загружаемая программа не найдена в массиве @INC, компилируется с ошибками или не возвращает истинного значения. Поэтому в конце загружаемого файла должно быть любое выражение, возвращающее истинное значение. По устоявшейся традиции выражение '1;' помещается в последней исполняемой строке файла. Поэтому, чтобы библиотека в нашем примере без ошибок загружалась командой require, в конце библиотечного файла добавим требуемую строку:

# ... другие подпрограммы библиотеки...

1; # вернуть истинное значение для require

__DATA__ # конец библиотечного файла

Команда require также регистрирует загруженные программы в специальном хэше %INC, поэтому не загружает их повторно. Однако использование библиотек и прочих внешних файлов в таком виде рано или поздно приводит к проблеме совпадения имен глобальных переменных и подпрограмм. Разные библиотеки, созданные разными программистами, неизбежно будут содержать одинаковые идентификаторы. Конфликт между совпадающими именами в разных программных файлах можно разрешить с помощью механизма пакетов.

Пакеты используются в Perl для разделения глобального пространства имен на задаваемые программистом подпространства. Отдельные пространства имен позволяют использовать в каждом из них собственный набор идентификаторов, не конфликтующих с одноименными идентификаторами в других пространствах. Пакет объявляется с помощью команды package, за которой указывается имя пакета. Имена пакетов, задаваемые программистом, принято начинать с заглавной буквы, в отличие от системных, которые записываются строчными буквами. Например:

package Package; # объявить пакет с именем Package

Подпрограммы и глобальные переменные, определенные после команды package, относятся к объявленному пакету. Действие команды package распространяется до конца текущего блока, файла, блока eval или до следующей команды package, начинающей или продолжающей указанный в ней пакет. Каждое употребление команды package означает переключение на соответствующее пространство имен, идентификаторы которого хранятся в собственной таблице имен. Специальная лексема __PACKAGE__ содержит имя текущего пакета. Поясним сказанное таким примером:

Поделиться:
Популярные книги

Газлайтер. Том 4

Володин Григорий
4. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 4

Гранит науки. Том 4

Зот Бакалавр
4. Герой Империи
Фантастика:
боевая фантастика
городское фэнтези
попаданцы
5.00
рейтинг книги
Гранит науки. Том 4

Я не князь. Книга XIII

Дрейк Сириус
13. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я не князь. Книга XIII

Локки 10. Потомок бога

Решетов Евгений Валерьевич
10. Локки
Фантастика:
фэнтези
юмористическое фэнтези
героическая фантастика
боевая фантастика
5.00
рейтинг книги
Локки 10. Потомок бога

Я все еще барон

Дрейк Сириус
4. Дорогой барон!
Фантастика:
боевая фантастика
5.00
рейтинг книги
Я все еще барон

ЖЛ 9

Шелег Дмитрий Витальевич
9. Живой лёд
Фантастика:
фэнтези
боевая фантастика
5.00
рейтинг книги
ЖЛ 9

Шайтан Иван 3

Тен Эдуард
3. Шайтан Иван
Фантастика:
попаданцы
альтернативная история
7.17
рейтинг книги
Шайтан Иван 3

Позывной "Князь"

Котляров Лев
1. Князь Эгерман
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Позывной Князь

Ермак. Телохранитель

Валериев Игорь
2. Ермак
Фантастика:
альтернативная история
7.50
рейтинг книги
Ермак. Телохранитель

На границе империй. Том 2

INDIGO
2. Фортуна дама переменчивая
Фантастика:
космическая фантастика
7.35
рейтинг книги
На границе империй. Том 2

Тактик

Земляной Андрей Борисович
2. Офицер
Фантастика:
альтернативная история
7.70
рейтинг книги
Тактик

Вперед в прошлое 6

Ратманов Денис
6. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 6

Мэр

Астахов Павел Алексеевич
Проза:
современная проза
7.00
рейтинг книги
Мэр

Я Гордый часть 6

Машуков Тимур
6. Стальные яйца
Фантастика:
фэнтези
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я Гордый часть 6