Control flow

return#

Leave the current subroutine, eval, do FILE, sort block, or regex eval block, yielding a value to the caller.

return is the explicit exit from a named or anonymous sub. It stops evaluation of the sub body at the point of call and hands EXPR back to whoever invoked the sub. The value EXPR produces depends on the caller’s context — list, scalar, or void — which the body can inspect with wantarray before deciding what to return.

Synopsis#

return EXPR
return

What you get back#

return itself does not have a return value — it does not continue in the current frame. It terminates the frame and the caller receives EXPR, evaluated in the caller’s context:

  • List contextEXPR is evaluated in list context; its list value is what the caller sees.

  • Scalar contextEXPR is evaluated in scalar context; its scalar value is what the caller sees.

  • Void contextEXPR is still evaluated (for side effects), but the value is discarded.

With no EXPR the caller receives:

  • list context — the empty list ()

  • scalar contextundef

  • void context — nothing

This asymmetry matters: return; (bare) is not the same as return undef;. A bare return in list context yields (), which is false and has zero elements; return undef; in list context yields a one-element list containing undef, which is true (because the list has one element). Error-signalling subs should almost always use bare return.

sub find_it {
    my ($key) = @_;
    return unless exists $cache{$key};  # bare: () in list, undef in scalar
    return $cache{$key};
}

if (my @hits = find_it($k)) { ... }     # () is false; undef-in-list is true

Context propagation with wantarray#

The caller’s context reaches the callee through wantarray:

A sub that wants to return shape-appropriate values inspects it:

sub stats {
    my @xs = @_;
    return unless @xs;                     # bare: () / undef as above
    my $sum = 0; $sum += $_ for @xs;
    my $avg = $sum / @xs;
    return wantarray ? ($sum, $avg) : $avg;
}

my ($s, $a) = stats(@data);                # list context  → two values
my $a       = stats(@data);                # scalar context → average only
stats(@data);                              # void context  → computed, discarded

The same call site can be evaluated in different contexts across different invocations; return re-resolves EXPR each time.

Implicit return: last expression wins#

If control reaches the end of a sub (or eval, or do FILE) without hitting return, the value of the last evaluated expression is returned, in the caller’s context. This is the idiomatic “trailing expression” style:

sub square { my ($x) = @_; $x * $x }      # implicit return of $x * $x

sub classify {
    my ($n) = @_;
    $n < 0   ? "negative"
  : $n == 0  ? "zero"
  : "positive"                             # trailing ternary is the value
}

Use explicit return when you exit early, or when the end of the sub is a statement (e.g. a loop, an assignment) whose value is not what you want the caller to see.

Examples#

Early exit on a guard:

sub lookup {
    my ($id) = @_;
    return unless defined $id;
    return $table{$id};
}

Return from an eval block without unwinding the enclosing sub:

sub try_parse {
    my ($text) = @_;
    my $parsed = eval {
        return {} if $text eq "";          # leaves eval, not try_parse
        parse($text);
    };
    return $@ ? undef : $parsed;
}

Context-sensitive return:

sub users {
    return wantarray ? @all_users : scalar @all_users;
}

my @u = users();                           # the users themselves
my $n = users();                           # how many there are

Parser exemption — return is not a looks-like-a-function operator:

sub greet { return ("hello") . " world" } # returns "hello world"
                                          # the . " world" is part of EXPR
greet();                                  # "hello world"

This is why return (EXPR) does not insulate EXPR from a trailing operator; anything after the closing paren is still argument to return. Same rule as print.

Illegal: return inside grep / map:

my @odd = grep { return $_ % 2 } @n;      # wrong; leaves the sub
my @odd = grep { $_ % 2 } @n;             # right

Inside a grep / map the block’s last expression is already the value; a return there exits the enclosing sub, which is almost never what you mean.

Edge cases#

  • Bare return vs return undef: as above, bare return yields () in list context, which lets if (my @x = f()) work as a “no results” test. return undef puts one element in the list and flips that test to true. Prefer bare return unless you specifically want a defined-undef scalar.

  • return from a sort comparator: legitimate and common in complex comparators:

    sort { return $a->[0] <=> $b->[0] || $a->[1] cmp $b->[1] } @rows;
    
  • return from do FILE: becomes the file’s value, which is what require and use inspect to decide module-load success. A .pm ending in 1; is the common idiom; return 1; near the top of the file is equivalent.

  • return from a regex (?{ ... }) block: ends the code block only, not the regex match. Rarely useful; normal block flow is almost always clearer.

  • Void-context side effects still happen: return expensive(); in void context still calls expensive(). return is not an optimisation hint.

  • Not a function, no parentheses needed: return is an operator, not a function. return(1, 2, 3) and return 1, 2, 3 are the same. The parser exemption above means parens around EXPR do not delimit it from the rest of the statement — parens are purely for grouping inside EXPR.

  • Return in a block form of eval: eval { return $x } leaves the eval with $x; $@ is cleared (no exception). To return from the enclosing sub via an exception, die instead.

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • wantarray — inspect the caller’s context so return can yield the right shape

  • caller — the other half of caller introspection; useful when a sub decides what to return based on who called it

  • evalreturn inside an eval block leaves the eval, not the enclosing sub

  • sub — how subroutines are defined and how implicit return interacts with the last expression

  • die — the non-local exit; use when you want to unwind past intermediate frames instead of returning through each one

  • last — exits a loop, not a sub; do not confuse the two