In Perl kan elke functie bepalen in welke context deze wordt aangeroepen: schalarisch, lijstvormig of void. De operator wantarray wordt gebruikt om de context te bepalen.
Voorbeeld:
sub foo { if (wantarray) { return (1, 2, 3); # Lijstvormig } else { return 42; # Schalarisch } } my @a = foo(); # (1, 2, 3) my $b = foo(); # 42 foo(); # Void context
Bijzonderheid: als wantarray niet correct wordt gebruikt, kunnen onverwachte waarden worden geretourneerd.
Wat retourneert een functie als deze afhankelijk van de context een array en een schaalaar retourneert, maar in void-context wordt aangeroepen?
Antwoord: In void-context wordt de teruggegeven waarde genegeerd, maar de uitvoeringscode van de vertakking via wantarray blijft bestaan. Daarom moet er afzonderlijke verwerking zijn als de functie bijwerkingen heeft. Bijvoorbeeld:
sub noisy { if (wantarray) { print "Opgeroepen in lijstcontext"; return (1,2,3); } elsif (defined wantarray) { print "Opgeroepen in schalarisch"; return 42; } else { print "Void!"; return; } }
Verhaal 1
Op een project vergat een ingenieur de verschillen in context. Een functie die een lijst van bestandsnamen retourneerde, "gaf" soms alleen het aantal bestanden terug (schalarische context) in plaats van de namen zelf — dit leidde tot dataverlies bij concatenatie met andere resultaten.
Verhaal 2
Bij de ontwikkeling van een API voor het parseren van headers retourneerden functies alleen een lijst als er expliciet een array aan de linkerkant was (
my @headers = parse_headers()), en als deze werd aangeroepen alsif (parse_headers()), werd alleen de eerste header geretourneerd. De bug werd niet meteen gevonden, omdat de verwerking logisch leek — maar de gedrag verschilde op verschillende plaatsen in het project.
Verhaal 3
Een functie voor het zoeken naar overeenkomsten in een bestand retourneerde een verschillend aantal resultaten afhankelijk van de context. Als gevolg hiervan traden er onverwachte fouten op bij doorgeven aan map of grep: map verwachtte een lijst, maar kreeg undef — en in schalarische context werd alleen het aantal gevonden overeenkomsten geteld. Het probleem werd pas na verschillende releases ontdekt.