$maximum = &max(3, 5, 10, 4, 6);
sub max {
my($max_so_far) = shift @_; # the first one is the largest yet seen
foreach (@_) { # look at the remaining arguments
if ($_ > $max_so_far) { # could this one be bigger yet?
$max_so_far = $_;
}
}
$max_so_far;
}
This code uses what has often been called the "high-water
mark" algorithm; after a flood, when the waters have surged and
receded for the last time, the high-water mark shows where the
highest water was seen. In this routine,
$max_so_far keeps track of our high-water mark,
the largest number yet seen.
The first line sets $max_so_far to
3 (the first parameter in the example code) by
shifting that parameter from the parameter array,
@_. So @_ now holds
(5, 10, 4, 6), since the
3 has been shifted off. And the largest number yet
seen is the only one yet seen:
3, the first parameter.
Now, the foreach loop will step through the
remaining values in the parameter list, from @_.
The control variable of the loop is, by default,
$_. (But, remember, there's no automatic
connection between @_ and $_;
it's just a coincidence that they have such similar names.) The
first time through the loop, $_ is
5. The if test sees that it is
larger than $max_so_far, so
$max_so_far is set to
5 -- the new high-water mark.
The next time through the loop, $_ is
10. That's a new record high, so it's
stored in $max_so_far as well.
The next time, $_ is 4. The
if test fails, since that's no larger than
$max_so_far, which is 10, so
the body of the if is skipped.
The next time, $_ is 6, and the
body of the if is skipped again. And that was the
last time through the loop, so the loop is done.
Now, $max_so_far becomes the return value.
It's the largest number we've seen, and we've seen
them all, so it must be the largest from the list:
10.