天天看點

Learning Perl: 4.3. Return Values

Learning Perl: 4.3. Return Values
Learning Perl: 4.3. Return Values

4.3. Return Values

The subroutine is always invoked as part of an expression even if the result of the expression isn't being used. When we invoked &marine earlier, we were calculating the value of the expression containing the invocation but then throwing away the result.

Many times, you'll call a subroutine and do something with the result. This means that you'll be paying attention to the return value of the subroutine. All Perl subroutines have a return valuethere'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 would 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. As Perl is chugging along in a subroutine, it is 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;
    $wilma = &sum_of_fred_and_barney;      # $wilma gets 7
    print "/$wilma is $wilma./n";
    $betty = 3 * &sum_of_fred_and_barney;  # $betty gets 21
    print "/$betty is $betty./n";      
That code will produce this output:
Hey, you called the sum_of_fred_and_barney subroutine!
    $wilma is 7.
    Hey, you called the sum_of_fred_and_barney subroutine!
    $betty is 21.      
That print statement is a debugging aid, so you can see you 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!
    }      
In this example, the last expression evaluated is not the addition; it's the print statement. Its return value will normally be 1, meaning "printing was successful,"[*] but that's not the return value you wanted. So be careful when adding additional code to a subroutine since the last expression evaluated will be the return value.
[*] The return value of print is true for a successful operation and false for a failure. You'll see how to determine the kind of failure later in the next chapter.

So, what happened to the sum of $fred and $barney in that second (faulty) subroutine? We didn't put it anywhere, so Perl discarded it. If you had requested warnings, Perl (noticing that there's nothing useful about adding two variables and discarding the result) would likely warn you about something like "a useless use of addition in a void context." The term void context is a fancy way of saying that the answer isn't being stored in a variable or used in any other way.

"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 $fred or $barney, so the value of one of those variables becomes the return value. You won't know if the return value will be $fred or $barney until you see what those variables hold at runtime.

These are all rather trivial examples. It gets better when you can pass different values for each invocation into a subroutine instead of relying on global variables. In fact, that's coming right up.

Learning Perl: 4.3. Return Values
Learning Perl: 4.3. Return Values
Learning Perl: 4.3. Return Values