map i grep to potężne funkcje Perl do pracy z tablicami:
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 i grep zmienna $_ domyślnie zawiera bieżący element. Modyfikacja $_ zmieni sam element oryginalnej tablicy, jeśli tablica jest przekazywana przez odwołanie lub $_ jest używane bezpośrednio (np. przy aliasowaniu przez foreach).map zawsze zwraca listę, grep — podzbiór oryginalnej listy.Pytanie: Co robi ten kod i dlaczego?
my @nums = (1..5); my @result = map { $_++ } @nums; print "@nums ";
Odpowiedź: Ten kod nie zmieni oryginalnej tablicy @nums. Operator $_++ zwiększa wartość zmiennej wewnątrz bloku, ale nie zapamiętuje tych zmian w oryginalnej tablicy, ponieważ map zwraca zmienioną wartość, ale oryginalna tablica nie jest dotknięta (o ile nie użyto aliasu przez foreach).
my @nums = (1..5); my @result = map { $_++ } @nums; # @result będzie (1,2,3,4,5), @nums się nie zmienia print "@nums "; # Wyświetli: 1 2 3 4 5
Historia W jednym z projektów programista spodziewał się, że po
map { $_++ } @array, sama tablica@arrayzostanie zmieniona. W rezultacie program działał z przestarzałymi wartościami, co doprowadziło do błędnych obliczeń podczas agregacji danych.
Historia W systemie raportującym podczas filtrowania tablicy przez
grep, wewnątrz bloku przypadkowo użyto polecenia przypisania$result = $_, przez co wszystkie elementy zostały nadpisane w tej samej zmiennej, tracąc źródło danych. To utrudniło debugowanie i prowadziło do strat w raportowaniu.
Historia W skrypcie integracyjnym stosowano zagnieżdżone
mapi zapomniano, że wewnętrzny kontekst również działa na tej samej zmiennej$_, co spowodowało nieprzewidywalne zachowanie podczas modyfikacji elementów, ponieważ wewnętrznymapnadpisał wartości w tablicy wynikowej.