это продолжение предыдущего мини-опуса, посвящённого трудностям освоения языка perl.
переходим к циклам. сначала рассмотрим while.
$i = 1; while ($i < 10) { if ($i > 3) { break; } print $i; $i++; }
ну, что увидим в браузере? думаете, ‘123’? а вот и нет. будет явлена комбинация ‘123456789’, свидетельствующая о том, что условие почему-то не срабатывает. и это на самом деле так. в perl нет операторов управления циклом break и continue. для этих целей придумано аж 3 новых: next, last и redo. таким образом, last — это break, next — continue, а redo — это тотже next, только цикл будет запущен без проверки условия. модификая кода выглядит так:
$i = 1; while ($i < 10) { if ($i > 3) { last; } print $i; $i++; }
в отличие от php в perl массивы и хеши обозначается отлично от переменных: @arr — массив, %hash — хеш. для обращения к какому-либо элементу массива/хеша синтаксис тоже различен: $arr[0] и $hash{‘zero’}. не знаю, хорошо это или плохо. как по мне, так это просто иначе.
есть ещё один замечательный итератор — foreach. на php, в простейшем случае, он выглядит так:
foreach ($arr as $v) { ... }
. этот же вариант на perl:
foreach $v (@arr) { ... }
для php программиста, пробующего perl, проблемы возникнут в случае, когда нужно будет получить значения ключей. вариант на php:
foreach ($arr as $k => $v) { ... }
. на perl код такой:
foreach $k (keys %hash) { ... }
или, для значений:
foreach $v (values %hash) { ... }
. как видно, отличия весьма существенны. но нельзя сказать, что вариант на php сильно предпочтительнее. но следующий вариант может вызвать недоумение:
foreach (keys %ENV) { print '$ENV{' . $_ . '} = ' . $ENV{$_} . "\n"; }
«Где же присваивание?» — задаст вопрос php-ник. хотя многие всё-таки догадаются, что значение каким-то образом помещено в переменную $_, и будут абсолютно правы. дело в том, что perl, в некоторых случаях, использует внутреннюю переменную $_ (наряду с некоторыми другими). в данном случае, код
foreach (keys %ENV) {
поместит значение очередного ключа хеша в переменную $_.
моё отношение к этому: да, вариант удобный. но в случае, когда потребуется вложенный итератор, данный вариант неприменим. поэтому совет: не следует особо полагаться на данную переменную; её использование может преподнести весьма неприятный сюрприз.
в php есть замечательная функция trim, которая обрезает пробельные символы в строке с обоих сторон, а также функция rtrim (её псевдоним chop), которая обрезает “пробелы” (естественно, включая перевод строки) справа. в perl есть функция chop, но она выполняет несколько иную функцию. более логично использовать chomp (которая удаляет лишь один концевой перенос строки). но это чревато последствиями: код, прекрасно работающий под windows, начнёт «глючить» на nix`ах. но к этому вернусь позже.
программисты php могут удивиться (в который уже раз) такому коду:
foreach (values %STR) { chomp; }
на самом деле, всё просто: во всех значениях хеша %STR удаляются концевой перевод строки. здесь снова нужно вспомнить переменную $_: foreach помещает очередное значение в эту переменную, а chomp без параметров считает, что операция выполняется над $_.
теперь можно вернуться к более подробному описанию функции chomp. допустим, есть строка $str = «\r\n»;. под windows, код
chomp $str;
приведёт к дому, что значение $str станет равно пустой строке. закачав этот скрипт на nix-сервер получим неожиданную неприятность: значение строки будет равно
$str = "\r";
оказывается, чтобы функция работала правильно, требуется изменить значение переменной $/ = «\r\n»;.
днём интернета
шоколадкой для работы мозга
коробочкой ароматного чая для бодрости
продлением хостинга на +1 месяц