Язык программирования Perl
Шрифт:
Замыкания можно создавать динамически при выполнении программы. Приведем пример функции, которая при каждом вызове создает замыкание и возвращает ссылку на него. При этом каждый раз создается новый экземпляр лексической переменной, замкнутый от доступа извне:
В этой лекции изложены основные сведения о подпрограммах в Perl. Мы продолжим изучение подпрограмм в лекции 13, где будет рассказано о библиотечных модулях, и в лекции 14, посвященной объектному программированию на Perl.
Лекция 13. Библиотеки, пакеты и модули
В этой лекции рассмотрена модульная организация программ на Perl. Знать ее совершенно необходимо, поскольку типичные программы сами размещаются в нескольких исходных файлах и не обходятся без подключения внешних библиотечных модулей. Правила организации программных единиц и приемы работы с пространствами имен и составляют тему обсуждения в этой лекции.
Цель лекции: освоить приемы использования в программе готовых модулей, а также научиться создавать собственные модули и управлять пространствами имен в программе с помощью пакетов.
Современные языки программирования предоставляют программистам средства для того, чтобы упорядочить свои наработки. Нетривиальная программа обычно представляет из себя некоторое количество файлов с исходными текстами, расположенных в нескольких каталогах. А большие программные комплексы образуют внушительную иерархию подкаталогов, содержащих десятки и сотни программных файлов. Универсальные подпрограммы принято сохранять в отдельных библиотечных файлах, чтобы обращаться к ним из разных программ. Сходные по назначению процедуры и функции объединяются в библиотеки подпрограмм. Библиотека программ на Perl - это файл, обычно с суффиксом .pl, где хранится произвольный набор подпрограмм для использования в других программах. (Этот суффикс иногда применяется для прикладных программ на Perl, но для них рекомендуется использовать суффикс .plx.) Для примера напишем небольшую программную библиотеку для работы с данными о музыкальных дисках и сохраним ее в файле 'lib/music_lib.pl':
Рассмотрим, как происходит обращение к библиотечным подпрограммам во время выполнения программы.
Чтобы воспользоваться подпрограммой из библиотечного файла, нужно в вызывающей программе загрузить библиотеку командой do 'file.pl'. Команда do
загружает любую Perl-программу из внешнего файла во время выполнения программы. Причем в библиотеке в свою очередь могут загружаться программные файлы по команде do. Кроме этого, do регистрирует загруженные программы в специальном хэше %INC. Если do не может найти или прочитать файл, она возвращает неопределенное значение undef и присваивает специальной переменной $! признак ошибки. Если do прочитала файл, но не может его скомпилировать, она возвращает undef и помещает сообщение об ошибке в специальную переменную .$@. Если файл успешно скомпилирован, do возвращает значение последнего вычисленного выражения.После того как внешний файл был успешно загружен, можно вызывать подпрограммы из загруженного библиотечного файла, как если бы они были описаны в текущей программе. В нашем случае это будет выглядеть так:
Обратите внимание, что в нашем примере явно указан путь к подкаталогу с библиотекой, что предполагает запуск программы из определенного каталога. Гораздо лучше сделать так, чтобы расположение библиотек не зависело от местонахождения вызывающей программы. Для этого в Perl имеется специальный массив @INC, в котором хранится список каталогов для поиска загружаемых исходных файлов. В этот массив по умолчанию включаются каталоги, где находятся системные библиотеки Perl. Чтобы на время выполнения программы добавить в этот список свои каталоги с библиотеками, можно воспользоваться опцией – I, указываемой в командной строке при запуске компилятора perl. Например, запустим на выполнение программу и укажем дополнительно искать файлы в каталоге /Shock/Mike/lib и его подкаталогах:
Тогда в программе можно указывать путь к библиотекам относительно одного из перечисленных в массиве @INC каталогов:
Другой способ добавить в массив @INC каталог для поиска загружаемых файлов - использовать директиву (прагму) use lib. Для этого в программе перед командой загрузки библиотеки нужно указать ее расположение, например так:
Команда загрузки внешних программ do считается устаревшей и употребляется все реже и реже. Вместо нее применяется команда require, имеющая целый ряд преимуществ. Эта команда вызывает ошибку, если загружаемая программа не найдена в массиве @INC, компилируется с ошибками или не возвращает истинного значения. Поэтому в конце загружаемого файла должно быть любое выражение, возвращающее истинное значение. По устоявшейся традиции выражение '1;' помещается в последней исполняемой строке файла. Поэтому, чтобы библиотека в нашем примере без ошибок загружалась командой require, в конце библиотечного файла добавим требуемую строку:
Команда require также регистрирует загруженные программы в специальном хэше %INC, поэтому не загружает их повторно. Однако использование библиотек и прочих внешних файлов в таком виде рано или поздно приводит к проблеме совпадения имен глобальных переменных и подпрограмм. Разные библиотеки, созданные разными программистами, неизбежно будут содержать одинаковые идентификаторы. Конфликт между совпадающими именами в разных программных файлах можно разрешить с помощью механизма пакетов.