Приглашаем посетить
Лесков (leskov.lit-info.ru)

Section 4.9.  The return Operator

Previous
Table of Contents
Next

4.9. 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 Perlto return a value immediately without executing the rest of the subroutine.

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

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 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 needed, but it doesn't hurt anything. However, many Perl programmers believe it's just an extra seven characters of typing.

4.9.1. Omitting the Ampersand

A few rules govern 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, like a built-in function. (But there's a catch hidden in those rules, 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[Section 4.9.  The return Operator] call:

[Section 4.9.  The return Operator] In this case, the function is the subroutine &shuffle. But it may be a built-in function as you'll see in a moment.

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

If Perl's internal compiler has seen the subroutine definition, that's generally okay, too; in that case, you can 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 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 their own code, it's not necessarily a mistake; perhaps they know 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, often 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.

[*] Then again, maybe it is a mistake; you can search the perlfunc and perlop manpages for that name to see if 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.

    Previous
    Table of Contents
    Next