Анимация
JavaScript
|
Главная Библионтека глобальных, а не локальных переменных, директива use strict ни к чему хорошему не приведет. Оператор local создает динамическую область действия. Она отличается от другой области действия, поддерживаемой Perl и значительно более понятной на интуитивном уровне. Речь идет об области действия ту - лексической области действия, иногда называемой «статической». В динамической области действия неременная доступна в том случае, если она находится в текущей области действия - пли в области действия всех кадров (блоков) стека, определяемых во время выполнения. Все вызываемые функции обладают полным доступом к динамическим неременным, поскольку последгше остаются глобальными, но получают временные значения. Лишь лексические переменные защищены от вмешательства извне. Если и это вас не убедит, возможно, вам будет интересно узнать, что лексические неременные примерно на 10 нроценгов быстрее динамических. Старый фрагмент вида: sub tunc { local($x $у) = @ почти всегда удается заменить без нежелательных последствий следующим фрагментом: sub tunc { my{$x, $у) = @ , # Единственный случай, когда подобная замена невозможна, - если работа программы основана на динамической области действия. Это происходит в ситуации, когда одна функция вызывает другую и работа второй зависит от доступа к временным версиям глобальных переменных $х и $у первой функции. Код, который работает с глобальными переменными и вместо нормальной передачи параметров издалека вытворяет нечто странное, в лучшем случае ненадежен. Хорошие программисты избегают подобных выкрутасов как чумы. Если вам встретится старый код вида: &func(*Global Array) sub tunc { local(.aliased array) = shift, for (@aliased array) { } вероятно, его удастся преобразовать к следующей форме: func(\@Global Array), sub tunc { ray $array ref = shift for (@$array ref) { } > 10.14. Переопределение функции 369 До появления в Perl нормальной поддержки ссылок, использовалась старая стратегия передачи тии-глобов. Сейчас это уже дело прошлое. 1> Смотри также- Описание функций local и щ врег1/ипс{1); разделы «Pnvate Variables via my()» и «Тешрогагу Values via \ocul()» perlsub(l); рецепты 10.2; 10.16. 10.14. Переопределение функции Проблема Требуется временно или постоянно переопределить функцию, однако функциям нельзя «присвоить» новый код. Решение Чтобы переопределить функцию, присвойте ссылку на новый код тип-глобу имени функции. Используйте local для временной замены. undef &grow, tt Заглушить жалобы -w на переопределение ♦grow = \&expand grow() tt Вызвать expandO local *grow = \&shrink, tt Только в границах блока grow() tt Вызывает shrink() Комментарий в отличие от переменных (но по аналогии с манипуляторами) функции нельзя напрямую ирисвоить нужное значение. Это всего лишь имя. Однако с ней можно выполнять многие операции, выполняемые с переменными, поскольку вы можете напрямую работать с таблицей символов с помощью тии-глобов вида .foo и добиваться многих интересных эффектов. Если присвоить тип-глобу ссылку, то при следующем обращении к символу данного типа будет использовано новое значение. Именно это делает модуль Exporter при импортировании функции или переменной из одного пакета в другой. Поскольку операции выполняются непосредственно с таблицей символов пакета, они работают только для пакетных (глобальных) переменных, но не для лексических. ♦one var = \%two Table, # %one var становится синонимом для %two Table *one big = \&two small, tt &one big становится синонимом для &two small С тии-глобом можно использовать local, но не ту. Из-за local синоним действует только в границах текущего блока. local .fred = \&barney, П временно связать &fred с &barney Если значение, присваиваемое тип-глобу, представляет собой не ссылку, а другой тин-глоб, то замена распространяется на все типы с данным именем. Полное присваивание тин-глоба относится к скалярным величинам, массивам, хэшам, функциям, файловым манипуляторам, манипуляторам каталогов и форматам. Следовательно, присваивание «Тор = * Bottom сделает переменную $Тор текущего пакета синонимом для $Bottom, @Тор - для @Bottom, %Тор - для %Bottom и &Тор - для &Bottom. Замена распространяется даже на соответствующие манипуляторы файлов и каталогов и форматы! Вероятно, это окажется лишним. Присваивание тин-глобов в сочетании с замыканиями позволяет легко и удобно дублировать функции. Представьте, что вам понадобилась функция для генерации HTML-кода, работающего с цветами. Например: Sstring = redCcareful here"); print Sstring; <FONT COLOR=red>careful here</FONT> Функция red выглядит так: sub red { "<FONT COLOR=red>@ </FONT>" } Если вам потребуются другие цвета, пишется нечто подобное: sub color font { my Scolor = shift; return "<FONT COLOR=Scolor>i8i </F0NT>"; sub red { color font("red", } sub green { color font("green", } sub blue { color font("blue", (? ) } sub purple { color font("purple", (? ) } # И T. Д. Сходство функций наводит на мысль, что общую составляющую можно как-то выделить. Для этого следует воспользоваться косвенным присваиванием тип-глобы. Если вы используете рекомендуемую директиву use strict, сначала отключите strict refs для этого блока. colors = qw(red blue green yellow orange purple violet); for my Sname (gcolors) { no strict refs; • Sname = sub { "<FONT COLOR=Sname>(8i </F0NT>" }; Функции кажутся независимыми, однако фактически код был откомпилирован лишь один раз. Подобная методика экономит время компиляции и память. Для создания полноценного замыкания все неременные анонимной подпрограммы должны быть лексическими. Именно поэтому переменная цикла объявляется с ключевым словом ту. Перед вами одна из немногочисленных ситуаций, в которых создание прототипа для замыкания оправдано. Если вам захочется форсировать скалярный контекст для аргументов этих функций (вероятно, не лучшая идея), ее можно записать в следующем виде: 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 |