Hello MikeyG,
GrandFather has already highlighted the loop while (<STDIN>) { ... } as a problem area in your code. I want to elaborate a little on the issues this raises, because one of them (context) is a key feature of the Perl language.
First, the existence of a loop in this part of the code makes little sense, since by this point the input has been read in and won’t change — so what’s the point of calculating the average of the same set of numbers more than once?
Second, what does while (<STDIN>) actually do? If you look at the documentation for Perl’s builtin readline function, you’ll see that <STDIN> is a convenient synonym for readline(*STDIN), which means that the expression <STDIN> is really a call to the readline function. Here is an extract from the documentation for that function:
In scalar context, each call reads and returns the next line until end-of-file is reached, whereupon the subsequent call returns undef. In list context, reads until end-of-file is reached and returns a list of lines.
So <STDIN> reads a single line from the keyboard, but only if it’s called in scalar context. You can see the difference in the following two assignments:
my $line = <FIN>; # reads one line from the file referenced by the
+ filehandle FIN
my @lines = <FIN>; # reads all the lines at once
The first reads a single line only, because assignment to a scalar variable imposes scalar context on the readline operation. But the second reads the whole file, because assignment to an array variable imposes list context on the operation.
And now the point: the condition of a while loop is evaluated in list context, so while (<STDIN>) goes on reading until it encounters end-of-file. On my Windows system, you can enter end-of-file from the keyboard by typing Control-Z followed by Return; but otherwise (if the user doesn’t know about Control-Z), you have an infinite loop.
Update (Apr 07, 2016): This is wrong, because the condition of a while loop is actually evaluated in scalar (boolean) context. The reason the while (<STDIN>) loop is not terminated by simply pressing Return is that the input line still contains a newline character, so Perl considers it “true.” My point should have been directed to the next line of code, $ave = average(<FIN>);, where, as the argument to a subroutine call, <FIN> is evaluated in list context.
See Context tutorial.
Hope that’s of interest,
|