map и grep — это мощные функции Perl для работы с массивами:
my @nums = (1, 2, 3, 4, 5, 6); my @squared = map { $_ * $_ } @nums; # (1, 4, 9, 16, 25, 36) my @even = grep { $_ % 2 == 0 } @nums; # (2, 4, 6)
map и grep переменная $_ по умолчанию содержит текущий элемент. Модификация $_ изменит сам элемент исходного массива, если массив передан по ссылке или явно используется $_ (например, при alias через foreach).map всегда возвращает список, grep — подмножество оригинального списка.Вопрос: Что делает следующий код и почему?
my @nums = (1..5); my @result = map { $_++ } @nums; print "@nums ";
Ответ: Этот код не изменит исходный массив @nums. Оператор $_++ увеличивает значение переменной внутри блока, но не сохраняет эти изменения в исходном массиве, т.к. map возвращает измененное значение, но оригинальный массив не затронут (если только не используется alias через foreach).
my @nums = (1..5); my @result = map { $_++ } @nums; # @result будет (1,2,3,4,5), @nums не меняется print "@nums "; # Выведет: 1 2 3 4 5
История В одном проекте разработчик ожидал, что после
map { $_++ } @array, сам массив@arrayбудет изменен. В результате программа продолжала работать со старыми значениями, что привело к неверным подсчетам при агрегации данных.
История В отчетной системе при фильтрации массива через
grep, внутри блока случайно использовали команду присваивания$result = $_, из-за чего все элементы были перезаписаны в одну и ту же переменную, потеряв источник данных. Это усложнило отладку и привело к потерям в отчетности.
История В интеграционном скрипте кода применяли вложенные
mapи забыли, что внутренний контекст также работает с общей переменной$_, что вызвало непредсказуемое поведение при модификации элементов, так как внутреннийmapзатер значения в результирующем массиве.