Новички в Perl 5 жалуются, что в языке нет инструмента для реверса строк. Функция reverse есть, но она почему-то не работает:
$ perl -E "say reverse 'привет'"
привет
Набрав опыта, они находят решение. Функция работает в двух режимах. В списковом контексте она реверсирует списки, а в скалярном – строки:
$ perl -E "say scalar reverse 'привет'"
тевирп
К сожалению, это – исключение из контекстной модели Perl. Большинство операторов и функций определяют контекст, после чего данные интерпретируются в этом контексте. + и * работают с числами,. работает со строками. Поэтому символ (или имя функции типа uc) определяет контекст. В случае с reverse это не так.
В Perl 6 мы учли ошибки прошлого. Поэтому реверс строк, списков, и инвертирование хэшей разделены:
# реверс строк – то бишь, переворот:
$ perl6 -e 'say flip "привет"'
тевирп
# реверс списков
# perl6 -e 'say join ", ", reverse <ab cd ef>'
ef, cd, ab
# инвертирование хэшей
perl6 -e 'my %capitals = Франция => "Париж", Англия => "Лондон";
say %capitals.invert.perl'
("Париж" => " Франция ", " Лондон " => " Англия ")
При инвертировании хэшей тип результата отличается от типа ввода. Поскольку значения хэшей не обязательно различаются, инвертирование хэша в хэш может привести к потерям данных. Поэтому возвращается не хэш, а список пар – а что делать с ним, решает программист.
Вот как делать недеструктивную операцию инвертирования:
my %inverse;
%inverse.push( %original.invert );
Когда пары с уже существующими ключами добавляются в %inverse hash, оригинальное значение не перезаписывается, а превращается в массив.
my %h;
%h.push('foo' => 1); # foo => 1
%h.push('foo' => 2); # foo => [1, 2]
%h.push('foo' => 3); # foo => [1, 2, 3]
Все три указанных оператора по возможности преобразовывают аргументы к тому типу, который они ожидают. Если вы передадите в flip список, он будет превращён в строку, и строка будет реверсирована.
Автор: SLY_G