Анимация
JavaScript
|
Главная Библионтека Initial state: 0x305108 $а=3, (!!) 0x305108 Ox3051fOO SCALAR 0x351f00 (•---(made by Perl) print 3 3 $$a $b\n, Рис. 11.3. Анонимные субъекты Оператор undef может использоваться с любой переменной или функцией Perl для освобождения занимаемой ей памяти. Однако не следует полагать, что при вызове undef всегда освобождается память, вызываются деструкторы объектов и т. д. В действительности оператор всего лишь уменьшает счетчик ссылок на 1. Без аргумента undef дает неопределенное значение. Записи Ссылки традиционно применялись в Perl для обхода ограничения, согласно ко-торо.му массивы и хэши могут содержать только скаляры. Ссылки являются скалярами, поэтому для создания массива массивов следует создать массив ссылок на массивы. Аналогично, хэши хэшей реализуются как хэши со ссылками на хэши; массивы хэшей - как массивы ссылок на хэши; хэши массивов - как хэши ссылок на массивы и т. д. Имея в своем распоряжении эти сложные структуры, можно воспользоваться ими для реализации записей. Запись представляет собой отдельную логическую единицу, состоящую из различных атрибутов. Например, запись, описывающая человека, может содержать имя, адрес и дату рождения. В С подобные вещи называются структурами (structs), а в Pascal - записями (RECORDs). В Perl для них не существует специального термина, поскольку эта концепция может быть реализована разными способами. Наиболее распространенный подход в Perl заключается в том, чтобы интерпретировать хэш как запись, где ключи хэша представляют собой имена нолей записи, а ассоциированные величины - значения этих полей. Например, запись «человек» может выглядеть так; $Nat = { Name => Leonhard Euler , Address => 1729 Ramanujan Lane\nMathworld, PI 31416 Birthday => 0x5bb55B0, Поскольку ссылка $NAT является скалярной величиной, ее можно сохранить в элементе хэша или массива с информацией о целой группе людей и далее использовать приемы сортировки, объединения хэшей, выбора случайных записей и т. д., рассмотренные в главах 4 и 5. Атрибуты записи, в том числе и «человека» из нашего примера, всегда являются скалярами. Конечно, вместо строк можно использовать числа, но это банально. Настоящие возможности открываются в том случае, если атрибуты записи также представляют собой ссылки. Например, атрибут "Birthday" может храниться в виде анонимного массива, состоящего из трех элементов: день, месяц и год. Выражение $person->{"BIrthday"}->[0] выделяет из даты рождения поле «день». Дата также может быть представлена в виде хэша, для доступа к полям которого применяются выражения вида $person->{ Birthday }->{ day }. После включения ссылок в коллекцию приемов перед вами откроются многие нетривиальные и полезные стратегии программирования. На этом этане мы концеитуально выходим за пределы простых записей и переходим к созданию сложных структур, которые представляют запутанные отношения между хранящимися в них данных. Хотя они могут использоваться для реализации традиционных структур данных (например, связанных списков), рецепты второй части этой главы не связаны ни с какими конкретными структурами. В них описываются обобщенные приемы загрузки, печати, копирования и сохранения обобщенных структур данных. Завершающая программа этой главы демонстрирует работу с бинарными деревьями. 1> Смотри также- perlref(l); регИо!(1); peiidsc(l). 11.1. Ссылки на массивы Проблема Требуется работать с массивом через ссылку. Решение Ссылка па массив создается следующим образом: $aref = \@аггау $апоп аггау = [1, 3, 5, 7, 9], $апоп сору = [ @аггау ] @$implicit creation = (2, 4, 6, 8, 10), Чтобы разыменовать ссылку на массив, поставьте перед ней символ @: push((a$anon array, 11), Или воспользуйтесь стрелкой с указанием индекса конкретного элемента в квадратных скобках: $two = $implicit creation->[0], Для получения индекса последнего элемента массива но ссылке или определения количества элементов в массиве применяется следующая запись: $last idx = $#$aref, $num items = @$aref, Дополнительные фигурные скобки повышают надежность и форсируют нужный контекст: $last idx = $#{ $aref }; $num items = scalar @{ $aref }; Комментарий Рассмотрим примеры использования ссылок на массивы: # Проверить, содержит ли Ssomeref ссылку на массив If (ref($someref) ne ARRAY) { die "Expected an array reference, not $someref\n"; print "@{$array ref}\n", # Вывести исходные данные @order = sort @{ $array ref }; # Отсортировать их push @{ $array ref }, litem; # Добавить в массив новый элемент Если вы не можете выбрать между использованием ссылки на именованный массив и созданием нового массива, существует простое правило, которое в большинстве случаев оказывается верным. Получение ссылки на существующий массив используется либо для возврата ссылки за пределы области действия, либо при передаче массива функции по ссылке. Практически во всех остальных случаях используется [@аггау], что приводит к созданию ссылки на новый массив с копиями старых значений. Автоматический подсчет ссылок в сочетании с оператором \ обладает большими возможностями; sub array ref { my @array; return \@array, $aref1 = array ref(); $aref2 = array ref(), При каждом вызове array ref функция выделяет для (Эаггау новый блок памяти. Если бы мы не вернули ссылку на @аггау, то занимаемая массивом память была бы возвращена при выходе из блока, то есть при завершении подпрограммы. Однако ссылка на (Эаггау продолжает существовать, поэтому Perl не освобождает память, и мы получаем ссылку на блок памяти, недоступный через таблицу символов. Такие блоки памяти называются анонимными, поскольку с ними не связано никакое имя. К определенному элементу массива, на который указывает ссылка $aref, можно обратиться в форме $$aref [4], но $afef->[4] делает то же самое и обладает большей наглядностью. print $array ref->[$N]; # Обращение к N-му элементу (лучший вариант) print $$array ref[$N]; # То же, но менее наглядно print ${$array ref}[$N]; # То же, но непонятно и уродливо 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 |