Achtergrond van de vraag:
Perl heeft vanaf het begin veel aandacht besteed aan het werken met arrays en lijsten van gegevens. Functies zoals map, grep en de foreach-lus stellen programmeurs in staat om bewerkingen op collecties beknopt en efficiënt uit te voeren, wat krachtige patronen van functioneel programmeren in één expressie mogelijk maakt.
Probleem:
Veel beginnende Perl-programmeurs verwarren wanneer ze map moeten gebruiken en wanneer foreach of grep, wat leidt tot een verkeerde keuze van het hulpmiddel en afname van de prestaties of leesbaarheid van de code. Bovendien leidt onoplettendheid ten aanzien van bijwerkingen (side effects) in de body van dergelijke expressies tot moeilijk te debuggen fouten.
Oplossing:
De juiste keuze van het hulpmiddel voor iteratie over gegevens hangt af van de taak:
map — wordt gebruikt voor het transformeren van de elementen van een lijst en het bouwen van een nieuwe resultaatlijst.grep — filtert elementen van de oorspronkelijke lijst op basis van een opgegeven voorwaarde.foreach — wordt gebruikt voor bijwerkingen en iteratieve verwerking, vaker zonder een teruggegeven waarde.Voorbeeldcode:
my @numbers = (1, 2, 3, 4, 5); my @squares = map { $_ * $_ } @numbers; # [1, 4, 9, 16, 25] my @even = grep { $_ % 2 == 0 } @numbers; # [2, 4] foreach my $n (@numbers) { print "Getal: $n "; # toont elk element }
Belangrijke kenmerken:
map en grep werken in een lijstcontext en retourneren een nieuwe lijst.foreach creëert geen nieuwe lijst, maar doorloopt gewoon de elementen.map of grep worden niet aanbevolen.Kan je veilig de array wijzigen binnen de body van map of grep?
Nee, omdat Perl over kopieën van de elementen van de lijst iteraties uitvoert, maar het wijzigen van de oorspronkelijke array kan leiden tot onverwachte resultaten of zelfs een oneindige lus.
Wat gebeurt er als je return gebruikt in de body van map of grep?
Een expressie return binnen een anonieme blok leidt tot het verlaten van de omringende subroutine, niet alleen van de body van map/grep, wat gevaarlijk is voor de logica van het programma.
Voorbeeldcode:
sub voorbeeld { my @data = (1, 2, 0, 4); my @result = map { return "oops" als $_ == 0; $_+1 } @data; # verlaat voorbeeld bij 0 }
Waarom moet map niet enkel voor bijwerkingen worden gebruikt?
Omdat map bedoeld is voor het genereren van nieuwe lijsten, en al zijn elementen onmiddellijk worden berekend. Voor bijwerkingen is het beter om foreach te gebruiken — dit is leesbaarder en vereist geen opslag van het resultaat.
In het project werd map gebruikt voor logging, zonder zich te interesseren voor de geretourneerde lijst.
Voordelen:
Nadelen:
Gebruik van foreach voor logging, en map alleen voor het genereren van nieuwe lijsten, zonder patronen te mengen.
Voordelen:
Nadelen: