Returning Values from Subroutines

Calling a subroutine by itself on one line is one way of splitting the execution of a script to a subroutine, but more useful is a subroutine that returns a value. With return values, you can nest subroutine calls inside expressions, use them as arguments to other subroutines, or as parts of other Perl statements (depending on whether the return value is appropriate, of course).

By default, the return value of a Perl script is the last thing that was evaluated in the block that defines the subroutine. So, for example, here's a short Perl script to read in two numbers and add them together:

$sum = &sumnums();
print "Result: $sum
";

sub sumnums {
    print 'Enter a number: ';
    chomp($num1 = <STDIN>);
    print 'Enter another number: ';
    chomp($num2 = <STDIN>);
    $num1 + $num2;
}

The fact that subroutines can return values is important for the first line in that example; the value of the $sum variable will only be set as a result of the &sumnum() subroutine being called. Inside the subroutine, the last line where the two numbers $num1 and $num2 are added together is the value that is returned from the subroutine, the value that gets assigned to $sum, and the value that gets printed as the result. The reason the sum of $num1 and $num2 is returned is that unless you explicitly tell Perl what to return, it returns the value of the last expression in the subroutine. For example, 42 would be returned if the last line of the subroutine was 42. The catch to this behavior is that although the last statement in the block is often the return value for the subroutine, that's not always the case. Remember, the rule is that the last thing evaluated is the return value for the subroutine—and that might not be the last statement in the block. With loops such as while loops or for loops, the last thing evaluated might be the test. Or with loop controls, it might be the loop control itself.

Because the return value of a subroutine isn't always readily apparent, it's a much better idea to create a subroutine that explicitly returns a value using return. return, which is actually a function, takes any expression as an argument and returns the value of that expression. So the last line of that &sumnums() subroutine might look like this:

return $num1 + $num2;

Want to return multiple values from a subroutine? No problem. Just put them in a list and return them that way (and then, in the main part of your script that called the subroutine in the first place, make sure you deal with that returned list in some way). For example, this snippet calls a subroutine that processes an array of values. That subroutine returns a list of three values which can then be assigned (using list assignments in parallel) to the variables $max, $min, and $count.

($max, $min, $count) = &process(@foo);
# ...
sub foo {
    # ...
   return ($value1, $value2, $value3);
}

What if you want to pass two or more discrete lists of elements out of a subroutine? That you can't do. The return function with a list argument flattens all sublists, expands all hashes, and returns a single list of elements. If you want discrete arrays or lists on the outside of a subroutine, you'll need to figure out a way of splitting that list into its component lists after the subroutine is done. This is not a problem specific to return values; Perl also uses this single-list method of getting arguments into a subroutine as well (more about that later).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset