In Perl, any function can determine in what context it is called: scalar, list, or void. The wantarray operator is used to determine the context.
Example:
sub foo { if (wantarray) { return (1, 2, 3); # List } else { return 42; # Scalar } } my @a = foo(); # (1, 2, 3) my $b = foo(); # 42 foo(); # Void context
A peculiarity: if wantarray is not used correctly, unexpected values can be returned.
What will the function return if, depending on the context, it returns an array and a scalar, but is called in void context?
Answer: In void context, the return value is ignored; however, the code execution branch based on wantarray remains. Therefore, separate handling should be provided if the function performs side effects. For example:
sub noisy { if (wantarray) { print "Called in list context"; return (1,2,3); } elsif (defined wantarray) { print "Called in scalar"; return 42; } else { print "Void!"; return; } }
Story 1
On a project, one engineer forgot about the differences in context. A function that returned a list of file names sometimes "gave" only the number of files (scalar context) instead of the actual names — this led to data loss when concatenating with other results.
Story 2
When developing an API for parsing headers, functions returned a list only if there was an array explicitly on the left (
my @headers = parse_headers()), but if called asif (parse_headers()), only the first header was returned. The bug was not found for a long time, as the processing seemed logical — but the behavior differed in different parts of the project.
Story 3
A function for finding matches in a file returned a different number of results depending on the context. As a result, when passing it to map or grep, unexpected errors occurred: map expected a list but got undef — while in scalar context, it counted only the number of found matches. The problem was discovered only after several releases.