Perl functions can be invoked in two contexts: list and scalar. These contexts indicate what is to be done with the return value. Functions can return different values in list context than in scalar context. For instance, the grep() function takes a list and a block or expression and filters out elements of the list for which the block or expression evaluates to false. The grep() function returns the filtered list when called in list context, but when called in scalar context, it merely returns the size of this list. That is, it returns the number of elements for which the block or expression evaluates to true.

Some functions do not define what they return in list or scalar context. For instance, according to the perlfunc manpage, the sort() function "sorts the LIST and returns the sorted list value. In scalar context, the behavior of 'sort()' is undefined."

Noncompliant Code Example (sort())

This noncompliant code example inadvertently assigns a scalar to the result of the sort() function.

sub ret {
  my $list = shift;
  my @list = @{$list};
  # ...
  return sort @list;
}

my @list = ( "foo", "bar", "baz");
my $result = ret @list;

The contents of $result are undefined because the sort() function's return value is not defined in a scalar context.

Compliant Solution (sort())

This compliant solution guarantees that the ret() function is called only in list context.

sub ret {
  my $list = shift;
  my @list = @{$list};
  # ...
  return sort @list;
}

my @list = ( "foo", "bar", "baz");
my @result = ret @list;

In this case, the @result array will contain the list {"bar", "baz", "foo"}.

Risk Assessment

Using an unspecified value can lead to erratic program behavior.

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

EXP33-PL

Medium

Unlikely

Low

P6

L2

Automated Detection

Tool

Diagnostic

Perl::Critic

Subroutines::ProhibitReturnSort

Bibliography

 


3 Comments

  1. Via email, Michael Greb says:
    > EXP33-PL
    >
    >> Perl functions can be invoked in two contexts: list and scalar.
    >
    > More of a nitpick, there is also void context, three main types.
    > Sometimes boolean conext is listed but usually classified as a special kind of scalar context.

    Perhaps. I got that statement from _Conway_, and I suspect it is supported by the manpages.

  2. You are, indeed, correct.  Docs for the wantarray function and the perlcheat manpage put void context at the level of scalar and list.  However, the perldata manpage says

    There are two major contexts: list and scalar.

    Leaving void context until the fifth paragraph.

  3. Yes, void context is what you have when wantarray() returns undef. 

    Outside of sort(), I can't think of any built-in functions that don't support both a list and scalar context.  And with user-defined functions, the behavior is entirely up to the author.  So you can really only rely on the documentation (or the implementation) to say what contexts are supported or not.