Анимация
JavaScript


Главная  Библионтека 

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

«Простым словом» (bareword) называется слово, не имеющее специальной грамматической интерпрс-тацнн и ингернретируе.мое как строка - Примеч перев.

Хотя тег DEFAULT не указывается в %EXPORT TAGS, он обозначает все содержимое EXPORT.

Все эти переменные не обязательно определять в каждом модуле. Ограничьтесь лишь теми, которые будут использоваться.

> Смотри также-

Документация но стандартному модулю Exporter, рецепты 12.7; 12.18

12.2. Обработка ошибок require и use

Проблема

Загружаемый модуль может отсутствовать в системе. Обычно это приводит к фатальной ошибке. Вы хотите обнаружить и перехватить эту ошибку.

Решение

Поместите require или use в eval, а eval - в блок BEGIN.

# Не импортировать BEGIN {

unless (eval require $nod ) { warn Couldn t load $nod $@

# Импортировать в текущий пакет BEGIN {

unless (eval use Smod ) {

warn couldn t load Smod $ia

Комментарий

Попытка загрузки отсутствующего или неполного модуля обычно должна приводить к аварийному завершению программы. Однако в некоторых сцхуациях программа должна продолжить работу - например, попытаться загрузить другой модуль. Как и при других исключениях, для изолирования ошибок компиляции применяется конструкция eval.

Использовать eval { БЛОК } нежелательно, поскольку в этом случае будут перехватываться только исключения времени выполнения, а use относится к событиям времени компиляции. Вместо этого следует использовать конструкцию eval СТРОКА , что позволит перехватывать и ошибки компиляции. Помните: вызов requi re для простого слова имеет несколько иной смысл, чем вызов requi re



die "None of @DBs loaded" unless Sfound;

Мы включаем eval в блок BEGIN, чтобы гарантировать загрузку модуля во время компиляции, а не во время выполнения.

> Смотри также-

Рецепт 10.12; рецепт 12.3. Функции eval, die, use и require описаны ъ perl-func(l).

12.3. Отложенное использование модуля

Проблема

Необходимо организовать загрузку модуля на определенной стадии работы программы или вообще отказаться от его загрузки при некоторых обстоятельствах.

Решение

Разбейте use на отдельные компоненты require и import, либо воспользуйтесь директивой use autouse.

Комментарий

Если программа проверяет свои аргументы и завершает работу с информационным сообщением или ошибкой, загружать неиспользуемые модули бессмысленно. Это лишь вызывает задержки и раздражает пользователей. Но как говорилось во введении, команды use обрабатываются во время компиляции, а не во время выполнения.

Наиболее эффективная стратегия состоит в проверке аргументов внутри блока BEGIN до загрузки модулей. Следующая программа перед загрузкой необходимых модулей проверяет, что она была вызвана ровно с двумя аргументами, каждый из которых является целым числом:

для переменной. Команда добавляет расширение .рт и преобразует : ; в разделитель каталогов вашей операционной системы - в каноническом варианте / (как в URL), но в некоторых системах используются \, ; и даже . .

Если вы хотите последовательно попытаться загрузить несколько модулей и остановиться на первом работающем, поступите так:

BEGIN {

my($found, laDBs, Srnod); $found = 0;

@DBs = qw(Giant::Eenie Giant::Meanie Mouse::Mynie Мое); for $mod (@DBs) {

if (eval "require Srood") {

$nod->iniport(); # При необходимости

Sfound = 1;

last;



12.3. Отложенное использование модуля 415

BEGIN {

unless (©ARGV == 2 && (2 == grep {/"\d+$/} ©ARGV)) { die "usage; $0 numl пит2\п";

use Some;;Module; use More;;Modules;

Похожая ситуация возникает в программах, которые при разных запусках могут использовать разные наборы модулей. Например, программа factors из главы 2 «Числа» загружает библиотеку вычислений с повышенной точностью лишь при вызове с флагом -Ь. Команда use в данном случае бессмысленна, поскольку она обрабатывается во время компиляции, задолго до проверки условия if. По этой причине мы используем команду require:

if ($opt b) {

require Math::BigInt;

Math::BigInt является не традиционным, a объектно-ориентированным модулем, поэтому импортирование не требуется. Если у вас имеется список импортируемых объектов, укажите его в конструкции qw() так, как это было бы сделано для use. Например, вместо:

use Fcntl qw(0 EXCL 0 CREAT 0 RDWR);

можно использовать следующую запись:

require Fcntl;

Fcntl->inport(qw(0 EXCL 0 CREAT 0 RDWR));

Откладывая импортирование до времени выполнения, мы сознательно идем на то, что оставшаяся часть программы не узнает об изменениях импортированной семантики, которые были бы видны компилятору при использовании use. В частности, не будут своевременно видны прототипы функций и переопределения встроенных функций.

Возникает идея - инкапсулировать отложенную загрузку в подпрограмме. Следующее, простое на первый взгляд решение не работает:

sub load fflodule {

require $ [0]; «НЕВЕРНО import $ [0]; «НЕВЕРНО

Понять причину неудачи непросто. Представьте себе вызов require с аргументом "Math; : BigFloat". Если это простое слово, :: преобразуется в разделитель каталогов операционной системы, а в конец добавляется расширение .рт. Но простая переменная интерпретируется как литерал - имя файла. Дело усугубляется тем, что Perl не имеет встроенной функции import. Существует лишь метод класса import, который мы пытаемся применить с сомнительным косвенным объектным синтаксисом. Как и в случае с косвенным применением файловых манипуляторов, косвенный объект можно использовать лишь для простой ска-



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