map en grep zijn krachtige functies in Perl voor het werken met arrays:
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 en grep bevat de variabele $_ standaard het huidige element. Het wijzigen van $_ verandert het element van de oorspronkelijke array als de array per referentie is doorgegeven of als $_ expliciet wordt gebruikt (bijvoorbeeld via alias met foreach).map retourneert altijd een lijst, grep retourneert een subset van de originele lijst.Vraag: Wat doet de volgende code en waarom?
my @nums = (1..5); my @result = map { $_++ } @nums; print "@nums ";
Antwoord: Deze code verandert de oorspronkelijke array @nums niet. De operator $_++ verhoogt de waarde van de variabele binnen het blok, maar slaat deze wijzigingen niet op in de oorspronkelijke array, omdat map de gewijzigde waarde retourneert, maar de oorspronkelijke array niet wordt aangetast (tenzij een alias wordt gebruikt via foreach).
my @nums = (1..5); my @result = map { $_++ } @nums; # @result zal (1,2,3,4,5) zijn, @nums verandert niet print "@nums "; # Zal afdrukken: 1 2 3 4 5
Verhaal In één project verwachtte een ontwikkelaar dat na
map { $_++ } @array, de array@arrayzou worden gewijzigd. Als gevolg hiervan bleef het programma werken met oude waarden, wat leidde tot onjuiste berekeningen bij het aggregeren van gegevens.
Verhaal In een rapportagesysteem, bij het filteren van de array met
grep, werd per ongeluk de toewijzing$result = $_gebruikt binnen het blok, waardoor alle elementen naar dezelfde variabele werden overschreven en de databon ontbrak. Dit maakte de foutopsporing moeilijker en leidde tot verliezen in de rapportage.
Verhaal In een integratiescript werden geneste
maps gebruikt en vergaten ze dat de interne context ook met de algemene variabele$_werkt, wat onvoorspelbaar gedrag veroorzaakte bij het wijzigen van elementen, omdat de internemapwaarden in de resulterende array overschreef.