# Analyze words in the input file or files
while (<>) {
foreach (split) { # break $_ into words, assign each to $_ in turn
$total++;
next if /\W/; # strange words skip the remainder of the loop
$valid++;
$count{$_}++; # count each separate word
## next comes here ##
}
}
print "total things = $total, valid words = $valid\n";
foreach $word (sort keys %count) {
print "$word was seen $count{$word} times.\n";
}
This one is a little more complex than most of our examples up to
this point, so let's take it step by step. The
while loop is reading lines of input from the
diamond operator, one after another, into $_;
we've seen that before. Each time through that loop, another
line of input will be in $_.
But didn't we just say that $_ holds one
line of input after another? Well, in the outer loop, that's
what it is. But inside the foreach loop, it holds
one word after another. It's no problem for Perl to reuse
$_ for a new purpose; this happens all the time.
Now, inside the foreach loop, we're seeing
one word at a time in $_.
$total is incremented, so it must be the total
number of words. But the next line (which is the point of this
example) checks to see whether the word has any nonword
characters -- anything but letters, digits, and underscores. So,
if the word is Tom's, or if it is
full-sized, or if it has an adjoining comma, quote
mark, or any other strange character, it will match that pattern and
we'll skip the rest of the loop, going on to the next word.
But let's say that it's an ordinary word, like
fred. In that case, we count
$valid up by one, and also
$count{$_}, keeping a count for each different
word. So, when we finish the two loops, we've counted every
word in every line of input from every file the user wanted us to
use.
We're not going to explain the last few lines. By now, we hope
you've got stuff like that down already.