Answers to Chapter 4 Exercises
- Here's one way to do it:
sub total { my $sum; # private variable foreach (@_) { $sum += $_; } $sum; }This subroutine uses
$sumto keep a running total. At the start of the subroutine,$sumisundef, since it's a new variable. Then, theforeachloop steps through the parameter list (from@_), using$_as the control variable. (Note: once again, there's no automatic connection between@_, the parameter array, and$_, the default variable for theforeachloop.)The first time through the
foreachloop, the first number (in$_) is added to$sum. Of course,$sumisundef, since nothing has been stored in there. But since we're using it as a number, which Perl sees because of the numeric operator+=, Perl acts as if it's already initialized to . Perl thus adds the first parameter to , and puts the total back into$sum.Next time through the loop, the next parameter is added to
$sum, which is no longerundef. The sum is placed back into$sum, and on through the rest of the parameters. Finally, the last line returns$sumto the caller.There's a potential bug in this subroutine, depending upon how you think of things. Suppose that this subroutine was called with an empty parameter list (as we considered with the rewritten subroutine
&maxin the chapter text). In that case,$sumwould beundef, and that would be the return value. But in this subroutine, it would probably be "more correct" to return as the sum of the empty list, rather thanundef. (Of course, if you wished to distinguish the sum of an empty list from the sum of, say,(3, -5, 2), returningundefwould be the right thing to do.)If you don't want a possibly undefined return value, though, it's easy to remedy: simply initialize
$sumto zero rather than using the default ofundef:my $sum = 0;
Now the subroutine will always return a number, even if the parameter list were empty.
- Here's one way to do it:
# Remember to include &total from previous exercise! print "The numbers from 1 to 1000 add up to ", &total(1..1000), ".\n";
Note that we can't call the subroutine from inside the double-quoted string,[383] so the subroutine call is another separate item being passed to
print. The total should be , a nice round number. And it shouldn't take any noticeable time at all to run this program; passing a parameter list of 1000 values is an everyday task for Perl.[383]We can't do this without advanced trickiness, that is. It's rare to find anything that you absolutely can't do in Perl.