Many times, we'll call a subroutine and actually do something
with the result. This means that we'll be paying attention to
the return value of the subroutine. All Perl
subroutines have a return value -- there's no distinction
between those that return values and those that don't. Not all
Perl subroutines have a useful return value,
however.
Since all Perl subroutines can be called in a way that needs a return
value, it'd be a bit wasteful to have to declare special syntax
to "return" a particular value for the majority of the
cases. So Larry made it simple. Every subroutine is chugging along,
calculating values as part of its series of actions. Whatever
calculation is last performed in a subroutine is
automatically also the return value.
For example, let's define this subroutine:
sub sum_of_fred_and_barney {
print "Hey, you called the sum_of_fred_and_barney subroutine!\n";
$fred + $barney; # That's the return value
}
The last expression evaluated in the body of this subroutine is the
sum of $fred and $barney, so
the sum of $fred and $barney
will be the return value. Here's that in action:
$fred = 3;
$barney = 4;
$c = &sum_of_fred_and_barney; # $c gets 7
print "\$c is $c.\n";
$d = 3 * &sum_of_fred_and_barney; # $d gets 21
print "\$d is $d.\n";
That code will produce this output:
Hey, you called the sum_of_fred_and_barney subroutine!
$c is 7.
Hey, you called the sum_of_fred_and_barney subroutine!
$d is 21.
That print statement is just a debugging aid, so
that we can see that we called the subroutine. You'd take it
out when the program is finished. But suppose you added another line
to the end of the code, like this:
sub sum_of_fred_and_barney {
print "Hey, you called the sum_of_fred_and_barney subroutine!\n";
$fred + $barney; # That's not really the return value!
print "Hey, I'm returning a value now!\n"; # Oops!
}
"The last expression evaluated" really means the last
expression evaluated, rather than the last line
of text. For example, this subroutine returns the larger value of
$fred or $barney:
sub larger_of_fred_or_barney {
if ($fred > $barney) {
$fred;
} else {
$barney;
}
}
The last expression evaluated is the single $fred
or $barney, which becomes the return value. We
won't know whether the return value will be
$fred or $barney until we see
what those variables hold at runtime.
sub list_from_fred_to_barney {
if ($fred < $barney) {
# Count upwards from $fred to $barney
$fred..$barney;
} else {
# Count downwards from $fred to $barney
reverse $barney..$fred;
}
}
$fred = 11;
$barney = 6;
@c = &list_from_fred_to_barney; # @c gets (11, 10, 9, 8, 7, 6)
In this case, the range operator gives us the list from
6 to 11, then
reverse reverses the list, so that it goes from
$fred (11) to
$barney (6), just as we wanted.