Return values#
A sub returns either by reaching its last statement, by hitting an explicit return, or by being goto-ed somewhere else (see recursion). The returned list is flattened the same way the argument list is — arrays and hashes lose their identity unless you return references — and is then evaluated in the caller’s context.
Implicit return#
If control falls off the end of the body, the value of the last expression statement is returned:
sub square {
my ($x) = @_;
$x * $x # implicit return
}
say square(5); # 25
Implicit return is idiomatic for short, one-expression subs. It is not idiomatic for multi-branch subs, where readers benefit from seeing every exit explicitly marked with return.
If the last statement is a control-flow construct (a for, while, if without an else, …), the returned value is unspecified. The empty sub returns the empty list.
Explicit return#
sub max {
my ($a, $b) = @_;
return $a if $a >= $b;
return $b;
}
Explicit return exits the sub immediately and supplies the return value. Multiple early returns are the standard shape for guarded code:
sub fetch {
my ($id) = @_;
return unless defined $id; # void/empty
return undef if $id eq ''; # explicit undef in scalar
...
}
Note the difference between return; and return undef;:
return;returns the empty list in list context,undefin scalar context, and nothing in void context. It is the context-correct way to say ”no result“.return undef;returns the list(undef)in list context, which has length 1 — so a caller writingif (my @r = my_sub()) { ... }will see a one-element list and theifwill fire. This is almost always wrong.
The rule of thumb: write return; to indicate failure or absence; write return undef; only when the caller is guaranteed to be in scalar context.
List flattening on return#
The same flattening that applies to arguments applies to return values:
sub two_lists {
my @a = (1, 2);
my @b = (3, 4);
return (@a, @b); # returns (1, 2, 3, 4) — one flat list
}
my ($x, $y) = two_lists(); # $x = 1, $y = 2 ; rest discarded
my @all = two_lists(); # @all = (1, 2, 3, 4)
my (@p, @q) = two_lists(); # @p = (1, 2, 3, 4), @q = ()
The last line is the classic surprise: @p greedily slurps the whole list because list-assignment to a flat array on the LHS has no way to know where one logical group ends and the next begins. To return two arrays distinctly, return references:
sub two_lists {
return (\@a, \@b);
}
my ($pref, $qref) = two_lists();
Context-sensitive return#
sub items {
if (wantarray) {
return (1, 2, 3); # list context
}
elsif (defined wantarray) {
return 3; # scalar context: count
}
else {
return; # void: nothing to compute
}
}
my @list = items(); # (1, 2, 3)
my $cnt = items(); # 3
items(); # discarded
The ”void early return“ branch is a real optimisation pattern — expensive computations should not run when the caller throws the result away.
For the full discussion of wantarray and how it composes with :lvalue, see lvalue and context.
Returning hashes and arrays#
Returning a @array or %hash directly works only because of flattening:
sub config {
return (host => 'localhost', port => 80);
}
my %c = config(); # %c is the hash
my @c = config(); # @c = ('host', 'localhost', 'port', 80)
For larger structures, return references:
sub config {
my %c = (host => 'localhost', port => 80);
return \%c; # one ref, no flattening
}
my $c = config();
say $c->{host};
References are also the only way to return multiple aggregates without the caller having to know their sizes.
return inside an eval#
return inside a do {} or eval {} block returns from the enclosing sub, not from the block:
sub safe {
my $result = eval {
return 'inside'; # this returns from `safe`, not from eval
};
return $result; # never reached
}
To exit just the eval, use a value ('inside' as the last expression of the block) — eval returns the value of its last expression like any other block.
Returning from BEGIN/END#
BEGIN, END, INIT, CHECK, and UNITCHECK blocks are subs in the technical sense but their return value is discarded. Don’t bother writing return ... inside them.
See also#
return— the keyword’s perlfunc page.wantarray— what your caller wants back.Lvalue subs and context — the full picture for context-sensitive subs.
Arguments and
@_— the symmetric story for what comes in.