- map BLOCK LIST
- map EXPR,LIST
Вычисляет BLOCK или EXPR для каждого элемента списка LIST (локально устанавливая
$_
равной каждому элементу) и возвращает список, объединяющий результаты всех таких вычислений. В скалярном контексте возвращает общее число сгенерированных элементов. Функция вычисляет BLOCK или EXPR в списковом контексте, поэтому каждый элемент списка LIST может производить ноль, один или более элементов в возвращаемом значении.@chars = map(chr, @nums);
транслирует список чисел в список соответствующих символов. Другой пример:
%hash = map { get_a_key_for($_) => $_ } @array;
является лишь своеобразным вариантом следующей записи:
%hash = (); foreach (@array) { $hash{get_a_key_for($_)} = $_; }
Заметим, что переменная
$_
представляет собой псевдоним значения списка, поэтому ее можно использовать для модификации элементов LIST. Хотя это удобно и поддерживается, но может привести к странным результатам если элементы LIST не являются переменными. Использование обычного циклаforeach
для этой цели может быть понятнее в большинстве случаев. См. также функцию grep -- возвращает массив, состоящий из тех элементов первоначального списка, для которых BLOCK или EXPR принимает значение "истина".Если в области видимости, над которой оперирует
map
, переменная$_
является лексической (так как была объявлена ключевым словомmy
), то, помимо того, что$_
представляет собой локальный псевдонимом списка элементов, она продолжает быть лексической внутри блока. Это значит, что переменная$_
не видна снаружи, предотвращая любые возможные побочные эффекты.Интерпретатор perl рассматривает фигурную скобку
{
, идущую послеmap
, как начало ссылки на хэш или как блок, т.еmap{ ...
может быть началом либоmap BLOCK LIST
, либоmap EXPR, LIST
. Поскольку Perl не смотрит закрывающую скобку}
, он должен предположить, с чем он имеет дело на основании того, что он находит после{
. Обычно он делает это правильно, но если он ошибся, то он этого не поймет, пока не доберется до}
и не встретить недостающую(или неожидаемую) запятую. В этом случае, синтаксическая ошибку будет указана ближе к}
, чтобы помочь интерпретатору Perl разобраться с ситуацией, измените что-либо около{
, например добавьте унарный+
.%hash = map { "\L$_" => 1 } @array; # perl предполагает EXPR. неправильно %hash = map { +"\L$_" => 1 } @array; # perl предполагает BLOCK. правильно %hash = map { ("\L$_" => 1) } @array; # это тоже работает %hash = map { lc($_) => 1 } @array; # как и это. %hash = map +( lc($_) => 1 ), @array; # это EXPR и это работает! %hash = map ( lc($_), 1 ), @array; # определяется как (1, @array)
или используйте
+{
, чтобы принудительно задать конструкцию анонимного хэша:@hashes = map +{ lc($_) => 1 }, @array # EXPR, поэтому требуется запятая в конце
в результате сгенерируется список ссылок на анонимные хэши, каждый из которых содержит одну запись.