Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
iakovlev.org
 

Пакеты и модули

Область имен - namespace - часть памяти программы со своей собственной областью видимости. Видимость переменных ограничена данным модулем .Модуль - пакет , который можно загружать и интегрировать с данной программой . В пакет может входить как один , так и несколько файлов-исходников . В следующем примере создается пакет, сохраняемый как файл package1.pl: package package1; BEGIN { } sub subroutine1 {print "Hello!\n";} return 1; END { } Чтобы использовать в программе код пакета, надо поместить в сценарий команду require: require 'package1.pl'; Теперь можно ссылаться на идентификаторы пакета package1, отделив его имя от идентификатора символами ::. require 'package1.pl'; package1::subroutine1(); print $package1::variable1; Hello! 1 Для того , чтобы не использовать префикс package1:: , нужно использовать модули . Модуль - пакет , оформленный в виде отдельного файла с расширением .pm. Модуль может содержать глобальные переменные . Создадим модуль Module1 package Module1; BEGIN { use Exporter (); @ISA = 'Exporter'; @EXPORT = '&subroutine1'; } sub subroutine1 {print "Hello!\n";} return 1; END { } Вызвать модуль можно так : use Module1; subroutine1(); Hello! Использование команды require отличается тем , что подключение модуля происходит в момент вызова , в то время как команда use подключает модуль на этапе компиляции . Имя текущего пакета можно определить с помощью встроенного идентификатора __PACKAGE__. В следует примере имя текущего пакета выводится из подпрограммы subroutine1, входящей в пакет package1: package package1; BEGIN {} sub subroutine1 { print __PACKAGE__; } return 1; END {} Если код пакета расположен в 2-х разных файлах , можно использовать команду require несколько раз : require 'file1.pl'; require 'file2.pl'; А можно и не вызывать 2 раза , а сделать например так : package package1; BEGIN {require 'package2.pl';} sub hello {print "Hello!\n";} return 1; END {} В код модуля можно встроить документацию с помощью операторов =pod и =cut : =pod (Начало встроенной документации) =item myTest1 Тут пошел 1-й комментарий ... =item myTest2 Тут пошел 2-й комментарий ... =cut (Конец встроенной документации) Чтобы из модуля разрешить экспорт подпрограммы , но по молчанию ее не загружать , нужно использовать @EXPORT_OK : package Module1; BEGIN { use Exporter(); @ISA = qw(Exporter); @EXPORT_OK = qw(&subroutine1); } sub subroutine1 {print "Hello!\n";} return 1; END { } Для вызова этой подпрограммы можно экспортировать ее явно : # use Module1 qw{&subroutine1); Если вы не хотите, чтобы модуль экспортировал в область глобальных имен свои имена, описанные как экспортируемые по умолчанию, надо добавить пару круглых скобок после имени модуля, указанного в команде use: use Module1 (); Если вы не хотите, чтобы модуль экспортировал определенные имена, их надо перечислить во время работы с модулем Exporter в массиве @EXPORT_FAIL : package Uptime; BEGIN { use Exporter; @ISA = qw/Exporter/; if ($^O ne 'MSWin32') { @EXPORT = qw/&uptime/; } else { print "Sorry, no uptime available in Win32.\n"; @EXPORT_FAIL = qw/&uptime/; } } sub uptime {print `uptime`;} return 1; END { } Задать номер версии в коде модуля можно так : $VERSION = 1.00; Проверить версию модуля можно так : use Module1(); Module1->require_version(2.00); Если в программе вызывается несуществующая процедура из какого-то модуля , это можно обработать с помощью AUTOLOAD : package Autoload; BEGIN { use Exporter (); @ISA = qw(Exporter); @EXPORT = qw(&AUTOLOAD); } sub AUTOLOAD () { my $subroutine = $AUTOLOAD; $subroutine =~ s/.*:://; print "You called $subroutine with these arguments: ", join(", ", @_); } return 1; END { } Следующий фрагмент показывает , что произойдет , если вызвать несуществующую подпрограмму : use Autoload; printem (1, 2, 3); Вывод будет такой : You called printem with these arguments: 1, 2, 3 Для каждого модуля можно определить свою собственную AUTOLOAD . Для выборочной загрузки отдельных частей модуля существует стандартный модуль AutoLoader : Для этого в модуле перед подпрограммами нужно поместить ключевое слово __END__ , а затем из командной строки обработать исходный файл модуля командой perl -w -e 'use AutoSplit; autosplit("%1", "%2")' где первый параметр - имя модуля , второй - каталог , где будет записан результат . Исходный код будет разбит на отдельные файлы с расширением .al . Чтобы модуль мог использовать механизм автозагрузки файлов, созданных с помощью autosplit, его главая часть должна быть организована специальным образом. Примером может служить модуль POSIX, который разбивает свои многочисленные подпрограммы на отдельные файлы и загружает их только тогда, когда они действительно требуются пользователю: package POSIX; use AutoLoader; ...... sub AUTOLOAD { $AutoLoader::AUTOLOAD = $AUTOLOAD; goto &Autoloader::AUTOLOAD; }
Оставьте свой комментарий !

Ваше имя:
Комментарий:
Оба поля являются обязательными

 Автор  Комментарий к данной статье