Анимация
JavaScript
|
Главная Библионтека Первая часть кода, не входящая в объявления функций, выполняется во время загрузки модуля. Для этого от пользователя модуля не потребуется никаких специальных действий. Впрочем, для кого-нибудь это может оказаться неприятным сюрпризом, поскольку при недоступности журнала die вызовет сбой при выполнении use или require. Блоки END не отличаются от других функций заверщения - trap О в командном интерпретаторе, atexit в языке С или глобальные деструкторы в объектно-ориентированных языках. Порядок выполнения END противоположен порядку загрузки модулей; иначе говоря, первым выполняется блок END последнего загруженного модуля. Завершающий код вызывается независимо от причины заверщения - нормального достижения конца основной программы, непосредственного вызова функции exit или необработанного исключения (например, die или ошибки деления на ноль). Однако с неперехваченными сигналами дело обстоит иначе. При завершении по сигналу блоки завершения не вызываются. Проблема решается следующей директивой; use sigtrap qw(die normal-signals error-signals) END также не вызывается в случае, если процесс вызывает функцию exec, поскольку процесс остается тем же самым, изменяется лишь программа. Все стандартные атрибуты (идентификатор процесса и его родителя, идентификаторы пользователя и группы, маска доступа, текущий каталог, переменные окружения, ограничения ресурсов и накопленная статистика), открытые файловые дескрипторы (однако см. описание переменной $"F в perlvar(l)) сохраняются. Другой подход привел бы к лишним вызовам блоков завершения в программах с ручной обработкой fork и exec. Это было бы нежелательно. t> Смотри также- Стандартная директива use sigtrap описана ъperlmod{\), а переменная $"F - в perldata(i). Функции fork и exec рассматриваются ъperlmod{\.). 12.7. Ведение собственного каталога модулей Проблема Вы не хотите включать собственные модули в стандартную библиотеку расширений системного уровня. Решение Возможно несколько вариантов: воспользоваться параметром командной строки Perl -I; присвоить значение переменной окружения PERL5LIB; применить директиву use lib (возможно, в сочетании с модулем FindBin). 12.7. Ведение собственного каталога модулей 423 Комментарий Массив @INC содержит список каталогов, которые просматриваются при каждой компиляции кода из другого файла, библиотеки или модуля командой do, require или use. Содержимое массива легко вывести из командной строки: % perl -е for (@INC) { printf %с1 %s\n, $i++, $ } 0 /usr/local/perl/llb/1686-linux/5.004 1 /usr/local/perl/llb 2 /usr/local/perl/llb/slte perl/i686-linux 3 /usr/local/perl/lib/site perl Первые два элемента (О и 1) массива @INC содержат обычные платформенно-за-висимый и платформенно-независимый каталоги, с которыми работают все стандартные библиотеки, модули и директивы. Этих каталогов два, поскольку некоторые модули содержат данные или форматирование, имеющие смысл лищь для конкретной архитектуры. Например, модуль Config содержит информацию, относящуюся лищь к некоторым архитектурам, поэтому он находится в О элементе массива. Здесь же хранятся модули, содержащие откомпилированные компоненты на С (например, Socket.so). Однако больщинство модулей находится в элементе 1 (независимый от платформы каталог). Следующая пара, элементы 2 и 3, по своим функциям аналогична элементам О и 1, но относится к конкретной системе. Допустим, у вас имеется модуль, который не поставлялся с Perl, - например, модуль, загруженный с CPAN или написанный вами. Когда вы (или, что более вероятно, ващ системный администратор) устанавливаете этот модуль, его компоненты попадают в один из этих каталогов. Эти каталоги следует использовать для любых модулей, удобный доступ к которым должен быть в ващей системе. Последний стандартный элемент, " " (текущий рабочий каталог), используется только в процессе разработки и тестирования программ. Если модули находятся в каталоге, куда вы перещди последней командой chdir, все хорошо. Если в любом другом месте - ничего не получится. Иногда ни один из каталогов, указанных в @INC, не подходит. Допустим, у вас имеются личные модули или ваша рабочая группа использует свой набор модулей, относящихся только к данному проекту. В этом случае необходимо дополнить поиск по стандартному содержимому @INC. В первом варианте решения используется флаг командной строки -1список ка-талогов. После флага указывается список из одного или нескольких каталогов, разделенных двоеточиями. Список вставляется в начало массива @INC. Этот вариант удобен для простых командных строк и потому может использоваться на уровне отдельных команд (например, при вызове простой однострочной программы из сценария командного интерпретатора). Подобную методику не следует использовать в строках #!. Во-первых, редактировать каждую программу в системе скучно. Во-вторых, в некоторых старых Или запятыми в MacOS. операционных системах имеются ошибки, связанные с ограничением длины этой строки (обычно 32 символа, включая #!). В этом случае очень длинный путь (например, #/opt/languages/f ree/extrabits/perl) приведет к появлению таинственной ошибки "Commancl not found". Perl пытается заново просканировать строку, но этот механизм недостаточно надежен и полагаться на него не стоит. Нередко самое удачное решение заключается в использовании переменной окружения PERL5LIB, значение которой обычно задается в стартовом сценарии интерпретатора. Если системный администратор задаст переменную в стартовом файле системного уровня, результаты будут доступны для всех пользователей. Предположим, ваши модули хранятся в каталоге -/perllib. Включите одну из следующих строк в стартовый файл командного интерпретатора (в зависимости от того, каким интерпретатором вы пользуетесь): # Синтаксис для sh, bash, ksh и zsh $ export PERL5LIB=$H0ME/perllib # Синтаксис для csh или tcsh % setenv PERL5LIB "/perllib Возможно, самое удобное решение с точки зрения пользователя - включение директивы use lib в начало сценария. При этом пользователям программы вообще не придется выполнять специальных действий для ее запуска. Допустим, у нас имеется гипотетический проект Spectre, программы которого используют собственный набор библиотек. Такие программы могут начинаться с команды: use lib "/projects/spectre/lib", Что делать, если точный путь к библиотеке неизвестен? Ведь проект может устанавливаться в произвольный каталог. Конечно, можно написать детально проработанную процедуру установки с динамическим обновлением сценария, но даже в этом случае путь будет жестко фиксироваться на стадии установки. Если позднее файлы переместятся в другой каталог, библиотеки не будут найдены. Модуль FindBin легко решает эту проблему. Он пытается вычислить полный путь к каталогу выполняемого сценария и присваивает его важной пакетной переменной $Bin. Обычно он применяется для поиска модулей в одном каталоге с программой или в каталоге lib того же уровня. Рассмотрим пример для первого случая. Допустим, у вас имеется программа /wherever/spectre/myprog, которая ишет свои модули в каталоге /wherever/spectrem, однако вы не хотите жестко фиксировать этот путь: use FindBin; use lib $FindBin::Bin; Второй случай - если ваша программа находится в каталоге /wherever/spectre/ bin/myprog, но ее модули должны находиться в каталоге /wherever/spectre/lib: use FmdBin qw($Bin); use lib "$Bin/. /lib"; 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 |