Всем привет, это снова я и Perl 6.
Вообще-то, изначально в планы входили по две публикации в неделю, но, очень скоро я вдруг осознал, что материала набегает на 9 глав, и месячник Perl 6 может затянуться на двумесячник. Не хотелось бы.
Поэтому снова здесь ликбез по Perl 6, продолжение искрометной первой и удивляющей второй главы, пятничная-последняя-статья-про-перл-на-этой-неделе-обещаю.
Новая глава называется «Циклы».
for
В Perl 6 цикл for нужен для тех типов данных, которые могут использовать итератор. По умолчанию, значение переменной помещается в $_. Следующий пример иллюстрирует вывод всех элементов массива @scores:
my @scores = <52 95 78>;
for @scores {
say $_;
}
Есть еще одна любопытная особенность цикла for — можно указывать действие перед самой инструкцией for:
.say for @scores;
Все, что находится внутри фигурных скобок { ... } называется лексическим блоком. В perl 6 лексические блоки могут получать параметры с помощью такой конструкции: ->.
my @scores = <52 95 78>;
for @scores -> $score {
say $score;
}
В этом примере у нас есть именованный параметр, сохраняющий результат итерации массива. По умолчанию, иакме переменные доступны только для чтения. Внутри цикла их изменять нельзя. Исправить эту ситуацию возможно с помощью «ключевого слова» is rw:
for @scores -> $score is rw {
say ++$score;
}
Можно передавать несколько параметров в блок:
for @scores -> $score is rw, $value {
say ++$score, " and ", $value;
}
Если есть необходимость сделать все параметры изменяемыми, т.е., is rw, то легко можно воспользоваться двунаправленной стрелкой: <->, она как раз и будет означать, что все параметры в блоке можно изменять:
for @scores <-> $score, $value {
say ++$score, " and ", ++$value;
}
Метод .kv возвращает список ключа и значения хеша попарно в виде списка. Блок может принимать несколько параметров, поэтому мы можем пробегать по ключам и значениям хеша таким образом:
my %ages = (Fred => 45, Bob => 33);
for %ages.kv -> $name, $age {
say "$name is $age years old";
}
Цикл loop
По сути, это переименованный цикл for из Perl 5, имеющий синтаксис языка C:
loop (my $i = 1; $i <= 42; $i++) {
say $i;
}
Да, теперь цикл for с таким синтаксисом не существует.
Просто одно слово loop, без дополнительных параметров, порождает бесконечный цикл:
loop {
my $cur_pos = get_position();
update_trajectory($target, $cur_pos);
}
while и until
Эти циклы в Perl 6 не изменились. Почти. Теперь можно опускать скобки вокруг выражений, что, в общем-то, справедливо для всех конструкций языка.
while $bar < 100 {
...
}
При необходимости, вы можете сохранить результат выражения внутри параметра и передать его в блок:
while something() -> $thing {
...
}
repeat
Этот цикл с пост-условием, которые могут быть взаимоземеняемыми:
repeat {
...
} while $x < 10;
совершенно аналогично этому:
repeat {
...
} until $x >= 10;
Если вас смущает присутствие until или while после блока цикла, то специально для таких, как вы, в Perl 6 есть заменяющая конструкция:
repeat while $x < 10 {
...
}
Конечно, работает и с until.






































07 августа 2009, 14:21
07 августа 2009, 14:23
07 августа 2009, 14:24
07 августа 2009, 14:42
07 августа 2009, 14:57
07 августа 2009, 15:14
10 августа 2009, 15:43
07 августа 2009, 14:28
Резюме статьи: лямбда-выражения (aka лексические блоки) + функция высшего порядка for.
В Haskell:
> map (x -> x + 1) [1,2,3,4]
(вернет [2,3,4,5])
> mapM print [1,2,3,4,5]
(распечатает список элементов по одному)
И короче, и понятнее, и единообразно (одни правила на весь язык, никаких "особых случаев").
07 августа 2009, 14:34
В Perl тоже есть map:
map { "Hello, $_!" } @names;
(Выведет приветствия всем элементам списка)
07 августа 2009, 14:35
Это я еще не все показал =))) Дальше будет еще веселее ;-)
10 августа 2009, 13:44
10 августа 2009, 13:46
10 августа 2009, 15:43