Анимация
JavaScript
|
Главная Библионтека Или в сочетании с циклом while: while (<FH>) { й Присвоить $ очередную прочитанную строку chomp; й Удалить из $ конечный символ \п, й если он присутствует foreach (split) { й Разделить $ по пропускам и получить @ й Последовательно присвоить $ й каждый из полученных фрагментов $ = reverse, й Переставить символы $ й в противоположном порядке print tt Вывести значение $ Многочисленные применинш $ заставляют понервничать. Особенно беспокоит то, что значение $ изменяется как в foreach, так и в while. Возникает вопрос - не будет ли полная строка, прочнта]Н1ая в $ через <FH>, навсегда потеряна после выполнения foreach? К счастью, эти опасения необоснованны - но крайней мере, в данном случае. Perl не уничтожает старое значение $ , поскольку переменная-итератор ($ ) существует в течение всего выполнения цикла. При входе во внутренний цикл старое значение автоматически сохраняется, а при выходе - восстанавливается. Однако причины для беспокойства все же есть. Если цикл while будет внутренним, а foreach - внеиишм, ваши страхи в полной мере оправдаются. В отличие от foreach конструкция while <FH> разрушает глобальное значение $ без предварительного сохранения! Следовательно, в начале любой процедуры (или блока), где $ используется в подобной конструкции, всегда должно присутствовать объявление local $ . Возможны и более сложные варианты. Команда last прерывает цикл, next переходит к следующему элементу, а redo возвращается к первой команде внутри блока. Фактически вы говорите: «Нет смысла продолжатВ, это не то, что мне нужно» (next), «Я нашел то, что искал, и проверять остальные элементы незачем» (last) или «Я тут кое-что изменил, так что проверки и вычисления лучше выполнить заново» (redo). Переменная, которой последовательно присваиваются все элементы списка, называется переменной цикла или итератором. Еслн итератор не указан, используется глобальная неременная $ . Она используется по умолчанию во многих строковых, списковых и файловых фушсциях Perl. В коротких программных блоках пропуск $ упрощает чтеппе программы (хотя в длитгых блоках излишек неявных допущений делает программу менее понятной). Например: foreach ( who ) { If (/tchrist/) { print, Если в области действия (scope) присутствует лексическая переменная (объявленная с шу), то временная переменная будет иметь лексическую область действия, 0фапиче1тую данным цикло.м. В противном случае она будет считаться гло-бс1Льно11 переменной с динамической областью действия. Во избелсапие странных побочных эффектов версия 5.004 допускает более наглядную и попятную запись: foreach my $item (©array) { print 1 = $item\n , Цикл foreach обладает еще одним свойством: в цикле переменная-итератор является не копией, а скорее синонимом (alias) текущего элемента. Иными словами, изменение итератора приводит к измепеиию каждого элемента списка. ©array = (1,2,3), foreach $item (©array) { $item--, print ©array , 0 1 2 # Умножить каждый элемент @a и @b на семь @а = ( 5, 3) @Ь = (О, 1) foreach $item (@а, @b) { .item »= 7, print Sitem , 3.5 21 0 7 Модификация списков в цикле foreach оказывается более попятпой и быстрой, чем в эквивалеитпом коде с циклом for и указанием кощфетпых индексов. Это пе ощибка; такая возможность была памерепно предусмотрена разработчиками языка. Не зиая о ней, можно случайно изменить содержимое списка. Теперв вы знаете. Например, применение s / к элементам списка, возвращаемого функцией values, приведет к модификации только копий, но не самого хэща. Однако срез хэша ©hash {keys %hash} (см. главу 5 «Хэши») дает нам нечто, что все же можно изменить с пользой для дела: # Убрать пропуски из скалярной величины, массива и всех элементов хэша foreach ($scalar, ©array, ©hash{keys %hash}) { s/-\s+ , s/\s+$ , По причинам, связанным с эквивалентными конструкциями командного интерпретатора Борна для UNIX, ключевые слова for и foreach взаимозаменяемы: for $item (©array) { # То же, что и foreach $item (©array) # Сделать что-то for (©array) { # То же, что и foreach $ (©array) Комментарий Приведенное решение предполагает, что у вас имеется скалярная переменная, содержащая ссылку на массив. Это позволяет делать следующее: ©fruits = ( Apple , Blackberry ), $fruit ref = \@fruits, foreach $fruit (@$fruit ref) { print Sfruit tastes good in a pie \n , Apple tastes good in a pie. Blackberry tastes good in a pie. Цикл foreach можно переппсать в цикле for следующего вида: for ($1=0, $1 <= $#$fruit ref, $1++) { print $fruit ref->[$i] tastes good in a pie \n. # Сделать что-то Подобный стиль часто показывает, что автор занимается nanncainieM hjhi сопровождением спепарнев интерпретатора и связан с системным адмиппстрнрова-ннем UNIX. Жизнь таких людеС! и без того сложна, поэтому не стоит судить их слишком строго. [> Смотри также- Разделы «Рог Loops», «Foreach Loops» и «Loop Control* perlsyn(iy, раздел «Тетрогагу Values via local()» perhub(l). Оператор local() рассматривается в рецепте 10.13, a my() - в рецепте 10.2. 4.5. Перебор массива по ссылке проблема Имеется ссылка па массив. Вы хотите использовать foreach для обращения к каждому элементу массг[ва. Решение Для перебора разыменованного (dereferenced) массива используется цикл foreach или for: # Перебор элементов массива $ARRAYREF foreach $item(i?$ARRAYREF) { # Сделать что-то с Sitem for ($1 = о, $1 <= $#$ARRAYREF, $l++) { tt Сделать что-то с $ARARAYREF->[$i] 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 |