The return Operator

The return operator immediately returns a value from a subroutine:

my @names = qw/ fred barney betty dino wilma pebbles bamm-bamm /;
my $result = &which_element_is("dino", @names);

sub which_element_is {
  my($what, @array) = @_;
  foreach (0..$#array) {  # indices of @array's elements
    if ($what eq $array[$_]) {
      return $_;         # return early once found
    }
  }
  −1;                    # element not found (return is optional here)
}

This subroutine is being used to find the index of "dino" in the array @names. First, the my declaration names the parameters: there’s $what, which is what we’re searching for, and @array, an array of values to search within. That’s a copy of the array @names, in this case. The foreach loop steps through the indices of @array (the first index is 0, and the last one is $#array, as you saw in Chapter 3).

Each time through the foreach loop, we check to see whether the string in $what is equal[*] to the element from @array at the current index. If it’s equal, we return that index at once. This is the most common use of the keyword return in Perl—to return a value immediately, without executing the rest of the subroutine.

But what if we never found that element? In that case, the author of this subroutine has chosen to return −1 as a “value not found” code. It would be more Perlish, perhaps, to return undef in that case, but this programmer used −1. Saying return −1 on that last line would be correct, but the word return isn’t really needed.

Some programmers like to use return every time there’s a return value, as a means of documenting that it is a return value. For example, you might use return when the return value is not the last line of the subroutine, such as in the subroutine &larger_of_fred_or_barney, earlier in this chapter. It’s not really needed, but it doesn’t hurt anything. However, many Perl programmers believe it’s just an extra seven characters of typing.

Omitting the Ampersand

As promised, now we’ll tell you the rule for when a subroutine call can omit the ampersand. If the compiler sees the subroutine definition before invocation, or if Perl can tell from the syntax that it’s a subroutine call, the subroutine can be called without an ampersand, just like a built-in function. (But there’s a catch hidden in that rule, as you’ll see in a moment.)

This means that if Perl can see that it’s a subroutine call without the ampersand, from the syntax alone, that’s generally fine. That is, if you’ve got the parameter list in parentheses, it’s got to be a function[*] call:

my @cards = shuffle(@deck_of_cards);  # No & necessary on &shuffle

Or if Perl’s internal compiler has already seen the subroutine definition, that’s generally okay, too; in that case, you can even omit the parentheses around the argument list:

sub division {
  $_[0] / $_[1];                   # Divide first param by second
}

my $quotient = division 355, 113;  # Uses &division

This works because of the rule that parentheses may always be omitted, except when doing so would change the meaning of the code.

But don’t put that subroutine declaration after the invocation, or the compiler won’t know what the attempted invocation of division is all about. The compiler has to see the definition before the invocation in order to use the subroutine call as if it were a built-in.

That’s not the catch, though. The catch is this: if the subroutine has the same name as a Perl built-in, you must use the ampersand to call it. With an ampersand, you’re sure to call the subroutine; without it, you can get the subroutine only if there’s no built-in with the same name:

sub chomp {
  print "Munch, munch!\n";
}

&chomp;  # That ampersand is not optional!

Without the ampersand, we’d be calling the built-in chomp, even though we’ve defined the subroutine &chomp. So, the real rule to use is this one: until you know the names of all of Perl’s built-in functions, always use the ampersand on function calls. That means that you will use it for your first hundred programs or so. But when you see someone else has omitted the ampersand in his own code, it’s not necessarily a mistake; perhaps he simply knows that Perl has no built-in with that name.[*] When programmers plan to call their subroutines as if they were calling Perl’s built-ins, usually when writing modules, they often use prototypes to tell Perl about the parameters to expect. Making modules is an advanced topic, though; when you’re ready for that, see Perl’s documentation (in particular, the perlmod and perlsub documents) for more information about subroutine prototypes and making modules.



[*] You noticed that we used the string equality test, eq, instead of the numeric equality test, ==, didn’t you?

[*] In this case, the function is the subroutine &shuffle. But it may be a built-in function, as you’ll see in a moment.

[*] Then again, maybe it is a mistake; you can search the perlfunc and perlop manpages for that name, though, to see whether it’s the same as a built-in. And Perl will usually be able to warn you about this when you have warnings turned on.

Get Learning Perl, 5th Edition now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.