Annotation 3 страница

  my ($var1, $var2, $var3) = (1, 2, 3); # правильно # запись my ($var1=1, $var2=2, $var3=3) ошибочна my $var4 = 4, $var5 = 5; # $var5 - глобальная, а не my   Чтобы проследить, как изменяются значения переменных, объявленных в главной программе и подпрограммах, внимательно прочитайте следующий пример (скучный, но полезный для понимания):   use strict; my $var = 'm'; # лексическая $var в main print "1(main)='$var'\n"; # выведет: 1(main)='m' sub1(); print "7(main):'$var'\n"; # выведет: 7(main):'z' sub sub1 { print "2(sub1)='$var'"; $var = 's'; # изменяется $var из main! print "-->'$var'\n"; # выведет: 2(sub1)='m'-->'s' my $var = '1'; # изменена $var из sub1 print "3(sub1)='$var'\n"; # выведет: 3(sub1)='1' sub2(); # снова видима $var1 из sub1 print "6(sub1):'$var'\n"; # выведет: 6(sub1):'1' } sub sub2 { # снова видима $var из main print "4(sub2):'$var'"; $var = 'z'; # изменяется $var из main!! print "-->'$var'\n"; # выведет: 4(sub2):'s'-->'z' my $var = '2'; # изменена $var1 из sub2 print "5(sub2)='$var'\n"; # выведет: 5(sub2)='2' }   Обратите внимание, что лексическая переменная $var, объявленная в главной программе, видима в обеих подпрограммах sub1 и sub2, поскольку они статически объявлены в рамках той же программы. Но при выполнении программы в подпрограмме sub2 не видима переменная $var, объявленная в процедуре sub1. Из приведенного примера видно, что после объявления в подпрограмме лексических переменных с помощью my(), изменения этих переменных не затрагивают других переменных с теми же именами. Поэтому, чтобы избежать нежелательного изменения значений переменных в других частях программы, рекомендуется всегда объявлять для переменных лексическую область видимости. Проконтролировать наличие объявлений для переменных в программе поможет прагма use strict. Другая разновидность лексических переменных, описываемых с помощью функции our, будет рассмотрена в следующей лекции.     В Perl имеется функция local(), также влияющая на область видимости переменных. Многие считают, что более удачным названием для нее было бы save(), потому что ее основное назначение - скрыть текущее значение глобальных переменных. Эта функция не создает локальных переменных, а делает "локальными" значения существующих глобальных переменных в текущей подпрограмме, блоке, eval или программном файле. Это значит, что после выполнения local текущие значения указанных переменных сохраняются в скрытом стеке, и новые значения переменных будут видимы вплоть до выхода из выполняемой подпрограммы, блока или файла, после чего восстанавливаются сохраненные значения переменных. На время действия local переменные остаются глобальными, поэтому новые временные значения переменных будут видимы и в вызываемых подпрограммах. Из-за временного характера действия функции local иногда говорят, что она описывает динамическую область видимости. Несколько переменных, чьи значения делаются временно скрытыми при помощи local, должны заключаться в круглые скобки, как показано ниже:   local $_; # временно скрыть значение буферной переменной local ($global1, $equant) = (1, 2); # правильно   Посмотрите, как изменится результат, если переписать предыдущий пример с использованием local вместо my в подпрограмме sub1:   $var = 'm'; # ГЛОБАЛЬНУЮ $var можно скрыть через local print "1[main]='$var'\n"; # выведет: 1[main]='m' sub1(); print "7[main]:'$var'\n"; # выведет: 7[main]:'s' sub sub1 { print "2[sub1]='$var'"; $var = 's'; # изменена $var из main! print "-->'$var'\n"; # выведет: 2[sub1]='m'-->'s' local $var = '1'; # значение ГЛОБАЛЬНОЙ $var скрывается print "3[sub1]#'$var'\n"; # выведет: 3[sub1]#'1' sub2(); print "6[sub1]:'$var'\n"; # выведет: 6[sub1]:'1' } sub sub2 { # видна ГЛОБАЛЬНАЯ $var из sub1 print "4[sub2]:'$var'"; $var = 'z'; # изменена $var из sub1! print "-->'$var'\n"; # выведет: 4[sub2]:'1'-->'z' my $var = '2'; # изменена $var из sub2 print "5[sub2]='$var'\n"; # выведет: 5[sub2]='2' }   Сравнивая эту программу с предыдущим примером, можно отметить следующие отличия. 1Переменную $var в главной программе пришлось сделать глобальной, так как local не может скрывать лексические переменные. 2Действие local распространяется до конца подпрограммы sub1, а также на вызываемую подпрограмму sub2. 3При выходе из подпрограммы sub1 действие local заканчивается и восстанавливается значение, которое содержала глобальная переменная $var до применения к ней local. В современных программах в основном используют функцию my для задания переменным лексической области видимости. Оправданное применение функции local в Perl обычно сводится к следующим случаям: 1Временное скрытие значения глобальных переменных, в том числе у специальных переменных. 2Временная модификация отдельных элементов массивов и хэшей, даже имеющих лексическую область видимости. 3Создание локальных файловых манипуляторов в версиях Perl до 5.6, не поддерживающих использование лексических переменных для хранения файловых манипуляторов.     С помощью ссылок, подпрограмм и лексических переменных создаются очень интересные информационные объекты, называемые замыканиями (closure). Они основаны на известном принципе, что объект ссылки сохраняется до тех пор, пока на него указывает хотя бы одна ссылка. А переменная может хранить ссылку на значение лексической переменной, динамически создаваемой при входе в блок и автоматически уничтожаемой при выходе из него. Это видно из следующего примера:   my $ref; # переменная для хранения ссылки { # в блоке создается my $lex_var = 'Суслик'; # переменная $lex_var $ref = \$lex_var; # в $ref помещена } # ссылка на переменную # $lex_var освобождается при выходе из блока print "Ты суслика видишь? И я не вижу. А он есть: "; print ${$ref}; # объект ссылки доступен через $ref   Подобным образом можно хранить ссылку на анонимную подпрограмму, из которой будут доступны динамически созданные лексические переменные. Такая подпрограмма, вызванная по ссылке, будет иметь доступ к области видимости этих переменных. Приведем пример простого замыкания:   my $ref; # переменная для хранения ссылки { # в блоке создается my $lex_var = 'Верблюд'; # переменная $lex_var $ref = sub { return $lex_var }; # в $ref помещена } # ссылка на подпрограмму # $lex_var освобождается при выходе из блока print &$ref; # объект возвращается подпрограммой по $ref   Замыкания можно создавать динамически при выполнении программы. Приведем пример функции, которая при каждом вызове создает замыкание и возвращает ссылку на него. При этом каждый раз создается новый экземпляр лексической переменной, замкнутый от доступа извне:   sub make_closure { # функция создания замыканий: my ($animal) = @_; # В лексической переменной # сохраняется аргумент функции my $ref2closure = sub { # и ссылка на # анонимную подпрограмму, return $animal; # которая имеет доступ }; # к лексической переменной. return $ref2closure; # возвращает ссылку на подпрограмму } # создаем 2 замыкания, сохраняя в них разные значения: my $camel1 = make_closure('дромадер'); # одногорбый верблюд my $camel2 = make_closure('бактриан'); # двугорбый верблюд print &$camel1, ' ', $camel2->(); # доступ по ссылкам   В этой лекции изложены основные сведения о подпрограммах в Perl. Мы продолжим изучение подпрограмм в лекции 13, где будет рассказано о библиотечных модулях, и в лекции 14, посвященной объектному программированию на 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__ содержит имя текущего пакета. Поясним сказанное таким примером:   package Package; # начало пакета Package $variable = 'переменная'; # скаляр из пакета Package sub subroutine { # подпрограмма из пакета Package return "$variable"; } package Another; # начало пакета Another $variable = 'переменная'; # скаляр из пакета Another sub subroutine { # подпрограмма из пакета Another return "$variable"; } package Package; # продолжение пакета Package @array = (1..5); # массив из пакета Package   В любом пакете можно обратиться к переменной или подпрограмме из другого пакета, указав ее полное имя. Полное имя (или квалифицированное имя) каждого нединамического программного объекта в Perl состоит из имени пакета и идентификатора. Символы :: разделяют эти две части таким образом:   $Package::variable - скалярная переменная из пакета Package $Another::variable - скалярная переменная из пакета Another &Package::subroutine - подпрограмма из пакета Package Package::subroutine - префикс подпрограммы можно не писать   Если глобальные имена не описаны явно в составе какого-либо пакета, то по умолчанию они относятся к пакету main. Можно считать, что объявление этого пакета неявно присутствует в начале любой Perl-программы. Поэтому упоминавшиеся до сих пор глобальные переменные, в том числе большинство специальных, на самом деле относятся к этому пакету. Имя пакета main обычно не указывается, но при необходимости принадлежность к нему можно указать явно:   %pseudo_name = ('Marylin Monroe' => 'Norma Jean'); print $main::pseudo_name{'Marylin Monroe'};   Следующие варианты записи имени обозначают одну и ту же переменную из пакета по умолчанию:   @main::array # с явным именем пакета main @::array # с пустым именем пакета @array # без имени пакета   Имена пакетов не применяются к лексическим переменным, объявленным с помощью функций my() и our() и существующим в собственном пространстве имен. Причем область действия переменных, определенных с помощью my(), не может распространяться за пределы исходного файла, а переменные, определенные с помощью our(), видны в пределах пакета, даже если части пакета определены в разных программных файлах. Вот пример сосуществования одноименных переменных из лексической области видимости и пространства имен пакета:   $variable = 'глобальная'; # переменная из пакета main my $variable = 'лексическая'; # переменная из текущего блока print "$main::variable $variable"; # будет напечатано: 'глобальная лексическая'   В Perl допускается использование пакетов, которые имеют составные имена следующего вида: Package::Subpackage. В этом случае имена пакетов образуют иерархию, а исходные файлы должны храниться в соответствующих вложенных каталогах. Составные имена пакетов соответствуют пути, по которому компилятор будет искать файл с исходным текстом программы. Загружать командой require исходный файл можно по полному имени файла с указанием подкаталогов, например:   use lib("$path/lib"); # добавить путь к списку поиска # загрузить внешнюю программу по имени файла require 'Package/Subpackage/Program.pm';   Если в команде require указано полное имя пакета в виде "голого слова" (bareword), а не в виде строки или переменной, то имя загружаемого файла формируется по следующему правилу. Разделитель пакетов '::' в имени пакета заменяется на разделитель каталогов в используемой операционной системе, а к имени файла добавляется суффикс .pm. Суффикс .pm используется для файлов, содержащих Perl-модули, и подразумевается по умолчанию командами require и use. Тогда предыдущую команду можно переписать так:   # загрузить внешнюю программу по имени пакета require Package::Subpackage::Program; # вызвать подпрограмму из загруженного пакета print Package::Subpackage::Program::subroutine(), "\n";   Теперь рассмотрим другой способ обращения к внешним программам - подключение их на этапе компиляции, что часто дает дополнительные преимущества.     Хотя есть немало случаев, когда нужно загружать внешние программы во время выполнения программы, гораздо чаще библиотеки модулей подключаются во время компиляции. Это делается с помощью команды use. Преимущество использования use по сравнению с require заключается в том, что все возможные ошибки выявляются до выполнения программы на этапе компиляции. Кроме того, команда use выполняет импорт имен, определенных в подключаемом модуле, после чего их можно удобно употреблять без имени пакета.   use Package::Subpackage::Module; # подключить модуль   С помощью команды use также подключаются многие стандартные модули Perl. Другие примеры использования команды use встретятся по ходу этой лекции при обсуждении работы с модулями. Команды require и use также применяются для контроля версии Perl, требуемой для компиляции и выполнения программы. Для этого параметром каждой из этих команд должно быть число, интерпретируемое как минимальный номер версии, который нужен, чтобы программа корректно выполнялась. Например:   use 5.005; # использовать версию Perl не ниже указанной require 5.008007; # использовать Perl 5.8.7 и выше   Если не выполняется требование, заданное в use, то компиляция завершится аварийно. Невыполнение требования, указанного в require, приведет к ошибке во время выполнения программы.     Модуль - это специальным образом оформленная библиотека подпрограмм, предназначенных для многократного использования. Модули появились в Perl, начиная с версии 5, и с тех пор подавляющее большинство универсальных Perl-программ оформляются в виде модулей. В отличие от обычных библиотек, модули имеют внешний интерфейс - ограниченный набор переменных и функций, предназначенных для использования другими программами. Доступ к внешнему интерфейсу модуля в вызывающей программе организуется с помощью механизма импортирования имен, реализованному в стандартном модуле Exporter. Приведем пример оформления типичного модуля (сохраненного в файле Module.pm):   package Module; # пространство имен модуля use 5.006001; # использовать версию Perl не ниже указанной use strict; # включить дополнительные проверки use warnings; # и расширенную диагностику our $VERSION = '1.00'; # версия модуля require Exporter; # загрузить стандартный модуль Exporter our @ISA = qw(Exporter); # неизвестные имена искать в нем our @EXPORT = qw( subroutine ); # имена, экспортируемые по умолчанию our @EXPORT_OK = qw( $variable ); # имена, экспортируемые по запросу $Module::variable = 'переменная 1'; # скаляр из модуля Module sub subroutine { # подпрограмма из модуля Module return "'подпрограмма 1 $Module::variable'"; } 1; __END__   Автоматически сгенерировать скелет нового модуля (а также сопутствующие файлы, необходимые для подготовки модуля к распространению) можно с помощью утилиты h2xs, входящей в состав дистрибутива Perl. Например, создать модуль с именем 'Module::Name' версии 1.00 можно такой командой:   h2xs -AX -n Module::Name -v 1.00   Если программа, которая обращается к этому модулю, использует только экспортированные по умолчанию имена, то используется форма команды use только с именем модуля:   use Module; # подключить модуль и # импортировать из него имена по умолчанию subroutine(); # вызвать подпрограмму &Module::subroutine()   В программе, в которой нужно явно затребовать перечисленные имена (с помощью метода import), применяется форма команды use со списком импортируемых имен:   use Module qw($variable); # затребовать импорт нужных имен print "$variable\n"; # скаляр $Module::variable   Антонимом команды use является команда no, которая неявно выполняет вызов метода unimport для отмены импортированных имен. В команде use также можно проверить, что версия подключаемого модуля соответствует требованиям. Для этого после имени модуля указывается минимальная требуемая версия:   use Module 1.00; # подключить модуль не ниже указанной версии   Помимо процедурного, модули могут иметь объектно-ориентированный интерфейс, который будет рассмотрен в следующей лекции.     В каждой Perl-программе могут присутствовать исполняемые блоки, фактически являющиеся специальными подпрограммами, которые обрабатываются особым образом. Они имеют зарезервированные имена и записываются заглавными буквами: BEGIN, END, CHECK, INIT. Каждый из таких блоков может присутствовать несколько раз в любом месте программы. Эти блоки вызываются автоматически в определенное время в начале и в конце выполнения Perl-программы. Блок BEGIN выполняется как можно раньше: во время компиляции сразу после того, как он полностью определен. Если определено несколько блоков BEGIN, то они выполняются в порядке их описания. Они используются командой use для загрузки внешних файлов во время компиляции программы. Блок END выполняется как можно позже: после того как perl закончил выполнение программы, перед завершением работы интерпретатора. Он выполняется даже в случае аварийного завершения программы. Несколько блоков END выполняются в порядке, обратном их размещению в файле. Блоки END не выполняются, если при запуске Рerl заказана только компиляция (опцией -c), или если компиляция завершается аварийно. При работе END доступна специальная переменная $?, содержащая код завершения программы, который можно изменить. Блок CHECK выполняется после того, как Рerl закончил компиляцию программы. Можно определить несколько блоков CHECK, тогда они будут выполняться в порядке, обратном их описанию. Блоки CHECK выполняются, если Рerl запущен с опцией -c только для компиляции программы. Блок INIT выполняется перед тем, как интерпретатор начнет выполнение программы, поэтому могут использоваться для инициализации модулей. Несколько блоков INIT выполняются в порядке их описания. Поясним последовательность выполнения специальных блоков на коротком примере:   print " 8. выполнение 1\n"; END { print "14. (1-й END)\n" } INIT { print " 5. (1-й INIT)\n" } CHECK { print " 4. (1-й CHECK)\n" } print " 9. выполнение 2\n"; BEGIN { print " 1. (1-й BEGIN)\n" } END { print "13. (2-й END)\n" } CHECK { print " 3. (2-й CHECK)\n" } INIT { print " 6. (2-й INIT)\n" } print "10. выполнение 3\n"; END { print "12. (3-й END)\n" } BEGIN { print " 2. (2-й BEGIN)\n" } INIT { print " 7. (3-й INIT)\n" } print "11. выполнение 4\n";   Сравните результаты запуска этого примера при обычном выполнении и только при компиляции:   Обычное выполнение: Только компиляция (perl -c) 1. (1-й BEGIN) 1. (1-й BEGIN) 2. (2-й BEGIN) 2. (2-й BEGIN) 3. (2-й CHECK) 3. (2-й CHECK) 4. (1-й CHECK) 4. (1-й CHECK) 5. (1-й INIT) 6. (2-й INIT) 7. (3-й INIT) 8. выполнение 1 9. выполнение 2 10. выполнение 3 11. выполнение 4 12. (3-й END) 13. (2-й END) 14. (1-й END)   Использование специальных блоков позволяет программисту гибко организовать контроль над программой на всех этапах ее жизненного цикла - от компиляции до завершения.     В поставке Perl имеется большое число стандартных библиотек модулей. Их описание можно прочитать в документации, обратившись к известной утилите:   perldoc perlmodlib   Стандартные модули находятся в библиотечных каталогах дистрибутива Perl и подключаются с помощью команды use. Встроенные системные функции находятся в специальном пакете CORE, поэтому, если в области видимости находится одноименная функция, то чтобы обратиться к встроенной функции, нужно вызвать ее по полному имени, например:   use Cwd 'chdir'; # подключить стандартный модуль chdir '/temp'; # вызвать Cwd::chdir() CORE::chdir '/temp'; # вызвать встроенную функцию chdir   Стандартные модули подразделяются на несколько групп. Одна из них - это модули прагм (pragmatic modules), которые контролируют поведение компилятора и исполняющей системы Perl. В качестве примера таких модулей можно привести constant, lib, locale, strict, utf8, warnings и другие. Другая группа - стандартные модули (standard modules), поставляемые вместе с системой программирования Perl. Приведем примеры стандартных модулей: AutoLoader, CPAN, Cwd, Encode, Exporter, File::Find, Math::BigInt, Time::localtime, Win32 и многие другие. Следующая группа - это модули расширения (extension modules), написанные на языке C и предназначенные для взаимодействия с операционной системой. Примерами модулей расширения могут служить Socket, Fcntl и POSIX.     В лекции 1 уже шла речь о Comprehensive Perl Archive Network (CPAN), что можно перевести как "Всеобъемлющая сеть Perl-библиотек", зеркальные сайты которой имеются по всему миру. Среди российских зеркал CPAN можно упомянуть http://cpan.sai.msu.ru/ и ftp://ftp.chg.ru/pub/lang/perl/CPAN/. CPAN - это огромный архив, где хранятся дистрибутивы Perl для разных операционных систем, документация, программы, библиотеки и модули по самой разной тематике, распространяемые бесплатно. На сайте имеется хорошая система поиска модулей. Кроме того, все модули расклассифицированы по логическим категориям и по именам пакетов, что облегчает поиск схожих модулей. В репозитарии CPAN на первом уровне иерархии насчитывается более 600 каталогов, в каждом из которых хранятся сотни модулей. Среди основных категорий модулей можно упомянуть важнейшие: [x]. интерфейсы операционных систем (такие как Win32); [x]. интерфейсы к системам управления базами данных; [x]. пользовательские интерфейсы; [x]. интерфейсы к другим языкам программирования; [x]. работа с файлами и файловыми системами; [x]. обработка строк и текстовой информации; [x]. интернационализация и локализация; [x]. аутентификация, безопасность и криптография; [x]. работа с сетями, WWW, HTML, HTTP, CGI, e-mail; [x]. архивирование и сжатие данных; [x]. работа с изображениями, чертежами, векторной и растровой графикой; [x]. работа с мультимедийными данными; [x]. и многое другое. Поэтому прежде, чем написать свою программу, имеет смысл поискать на CPAN модуль, подходящий для решения возникшей задачи. Во многих случаях "изобретать велосипед" не придется: найденный модуль либо можно сразу использовать, либо взять за основу своей разработки. Поскольку большинство современных Perl-модулей - объектно-ориентированные, они предполагают довольно легкую адаптацию путем определения подклассов, расширяющих возможности описанных в модуле классов. Даже если нужный модуль не найден, можно почерпнуть решения, реализованные в сходных модулях, изучив тексты программ, поскольку все модули распространяются в исходных кодах. CPAN является выдающимся собранием культурных ценностей, коллективной сокровищницей программистской мысли, реализованной в виде готовых к эксплуатации модулей.     Когда требуемый модуль отсутствует в вашей системе, его можно установить из репозитория CPAN. Для этого нужно обратиться к одному из зеркал этого архивного сайта и загрузить с него последнюю версию модуля, которые по традиции распространяются в виде архивов в формате tar.gz. Программисты, работающие с одной из операционных систем семейства Unix, могут устанавливать модули несколькими способами. Самый простой из них - воспользоваться утилитой cpan из дистрибутива Perl. Тогда для установки модуля прямо с ближайшего из зеркал сайта CPAN нужно выполнить, например, такую команду: