Анимация
JavaScript
|
Главная Библионтека Команда use работает аналогично, но с двумя дополнительными свойствами: загрузкой модуля на стадии компиляции и автоматическим импортированием. Модули, включаемые командой use, обрабатываются на стадии компиляции, а обработка require происходит во время выполнения. Это существенно, поскольку при отсутствии необходимого модуля программа даже не запустится - use не пройдет компиляцию сценария. Другое преимущество use перед require заключается в том, что компилятор получает доступ к прототипам функций в подпрограммах модуля. Прототипы принимаются во внимание только компилятором, но не интерпретатором (впрочем, как говорилось выще, мы рекомендуем пользоваться прототипами только для замены встроенных команд, у которых они имеются). Обработка команды use иа стадии компиляции позволяет передавать указания компилятору. Директива (pragma) представляет собой специальный модуль, влияющий на процесс компиляции Perl-кода. Имена директив всегда записываются в нижнем регистре, поэтому при написании обычного модуля следует выбирать имена, начинающиеся с большой буквы. К числу директив, поддерживаемых Perl 5.004, принадлежат autouse, constant, diagnostics, integer, lib, locale, overload, sigtrap, strict, subs и vars. Каждой директиве соответствует отдельная страница руководства. Другое отличие use и require заключается в том, что use выполняет неявное гш-портирование пакета включаемого модуля. Импортирование функции или переменной из одного пакета в другой создает некое подобие синонима - иначе говоря, появляются два имени, обозначающих одно и то же. Можно провести аналогию с созданием ссылки на файл, находящийся в другом каталоге, ко.маидой In / somedir/somefile. После подключения уже ие придется вводить полное имя для того, чтобы обратиться к файлу. Аналогично, импортирова1пюе имя не приходится уточнять именем пакета (или заранее объявлять с помощью use vars или use subs). Импортированные переменные можно использовать так, словно они являются частью вашего пакета. После импортирования $English: : OUTPUT AUTOFLUSH в текущий пакет на нее можно ссылаться в виде $OUTPUT AUTOFLUSH. Модули Perl должны иметь расширение .рт. Например, модуль FileHandle хранится в файле File Handle.рт. Полный путь к файлу зависит от включаемых путей, хранящихся в глобальном массиве @INC. В рецепте 12.7 показано, как работать с этим массивом. Если имя модуля содержит одну или несколько последовательностей : :, они преобразуются в разделитель каталогов вашей системы. Следовательно, модуль File::Find в большинстве файловых систем будет храниться в файле File/Find.pm. Например: require "FileHandle pm"; require FileHandle; use FileHandle; # Загрузка во время выполнения # Предполагается ".pm"; # то же, что и выше # Загрузка во время компиляции require "Cards/Poker, pm"; require Cards;:Poker; use Cards; ;Poker; # Загрузка во время выполнения # Предполагается ".pm"; # то же, что и выше # Загрузка во время компиляции Правила импортирования/экспортирования Процесс экспортирования демонстрируется ниже на примере гапотетического модуля Cards::Poker. Программа хранится в файле Poker.pm в каталоге Cards, то есть Cards/ Poker.pm (о том, где должен находиться каталог Cards, рассказано в рецепте 12.7). Приведем содержимое этого файла с пронумерованными для удобства строками: 1 package Cards :Poker, 2 use Exporter, 3 @ISA = (Exporter), 4 laEXPORT = qw(&shuffle iacard deck), 5 iacard deck = (), # Инициализировать глобальные # переменные пакета 6 sub shuffle { } # Определение # заполняется позднее 7 1 # Не забудьте! 8 строке 1 объявляется пакет, в который модуль поместит свои глобальные переменные и функции. Обычно модуль начинается с переключения на конкретный пакет, что позволяет ему хранить глобальные переменные и функции так, чтобы они не конфликтовали с переменными и футпсциями других программ. Имя пакета должно быть записано точно так же, как и при загрузке модуля соответствующей командой use. Не пишите package Poker только потому, что модуль хранится в файле Poker.pml Используйте package Cards::Poker, поскольку в пользовательской программе будет стоять команда use Cards: Poker. Эту распространенную ошибку трудно обнаружить. Если между командами package и use нет точного соответствия, проблемы возникнут лишь при попытке вызвать импортированную функцию или обратиться к импортированной переменной - те будут загадочным образом отсутствовать. Строка 2 загружает модуль Exporter, управляющий внешним РН1терфейсом модуля (см. ниже). Строка 3 инициализирует специальный, существующий на уровне пакета массив @ISA строкой "Exporter. Когда в программе пользователя встречается команда use Cards; ;Poker, Perl неявно вызывает спецпальный метод, Cards - : Poker->ifflport(). В пакете нет метода import, по это нормально - такой метод есть в пакете Exporter, и вы наследуете его благодаря присваиванию ©ISA (ISA = «is а», то есть «является»). Perl обращается к массиву @ISA пакета при обращении к неопределенному методу. Наследование рассматривается в главе 13 «Классы, объекты и связи». Пока не обращайте на него внимания, по не забывайте вставлять код строк 2 и 3 в каждый новый модуль. Строка 4 заносит список (Sshuffle, (acard deck) в специальный, существующий на уровне пакета массив @EXPORT. При импортировании модуля для переменных и функций, перечисленных в этом массиве, создаются синонимы в вызывающем пакете. Благодаря этому после импортирования вам не придется вызывать функцию в виде Рокег: :Deck: ;shuffle(23) - хватит простого shuffle(23). Этого не произойдет при загрузке Cards::Poker командой require Cards; ;Poker; импортирование выполняется только для use. Строки 5 и 6 готовят глобальные переменные и функции пакета к экспортированию (конечно, вы предоставите более конкретные инициализации и определе- ния, чем в нашем примере). Добавьте другие переменные и функции, включая и те, которые не были включены в внешний интерфейс посредством (ЭЕХРОВТ. Об использовании модуля Exporter рассказано в рецепте 12.1. Наконец, строка 7 определяет общее возвращаемое значение модуля. В нашем случае это просто 1. Если носледнее вычисляемое выражение модуля не дает истинного значения, инициируется исхииочение. Обработка исключений рассматривается в рецепте 12.2. Подойдет любое истинное выражение, будь то 6.02е23 или "Because tchrist and gnat told us to put this here"; однако 1 - каноническая истинная величина, используемая почти во всех модулях. Пакеты обеспечивают группировку и организацию глобальных идентификаторов. Они не имеют ничего общего с ограничением доступа. Код, откомпилированный в пакете Church, может свободно просматривать и изменять реремеиные пакета State. Пакетные переменные всегда являются глобальными и общедоступными. Но это вполне нормально, поскольку модуль представляет собой больше, чем простой пакет; он также является файлом, а файлы обладают собственной областью действия. Следовательно, если вам нужно ограничить доступ, используйте лексические переменные вместо глобальных. Эта тема рассматривается в рецепте 12.4. Другие типы библиотечных файлов Библиотека представляет собой набор неформально взаимосвязанных функций, используемых другими программами. Библиотеки не обладают жесткой семантикой модулей Perl. Их можно узнать но расширению файла .р1 - напри.мер, syslog.pl и chat2.pl. Библиотека Perl (а в сущности, любой файл, содержащий код Perl) может загружаться командой do file.pl или require fil. pi. Второй вариант лучше, поскольку в отличие от do require выполняет неявную проверку ощибок. Команда инициирует исключение, если файл не будет найден в пути @INC, не компилируется или не возвращает истинного значения при выполнении инициализирующего кода (последняя строка с 1, о которой говорилось выше). Другое преимущество require заключается в том, что команда следит за загруженными файлами с помощью глобального хэша %INC. Если %INC сообщает, что файл уже был загружен, он не загружается повторно. Библиотеки хорошо работают в программах, однако в ситуациях, когда одна библиотека использует другую, могут возникнуть проблемы. Соответственно, простые библиотеки Perl в значительной степени устарели и были заменены более современными модулями. Однако некоторые программы продолжают пользоваться библиотеками, обычно загружая их командой require вместо do. В Perl встречаются и другие расширения файлов. Расширение .рк используется для заголовочных файлов С, преобразованных в библиотеки Perl утилитой h2ph (см. рецепт 12.14). Расширение xs соответствует исходному файлу С (возможно, созданному утилитой h2xs), скомпилированному утилитой xsubpp и компилятором С в машинный код. Процесс создания смешанных модулей рассматривается в рецепте 12.15. До настоящего времени мы рассматривали лишь традиционные модули, которые экспортируют свой интерфейс, предоставляя вызывающей стороне прямой доступ к некоторым подпрограммам и переменным. К этой категории относится 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 [ 130 ] 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |