Gentlemen, what peril awaits me if I use
for (<>){...} loops instead of
while(<>){...} loops?
I got the idea from perlsyn:
'Instead of using "given()", you can use a "foreach()" loop.'
And indeed I can now use when() without an enclosing given().
They are very similar, but as others pointed out, for(<>) reads in
the entire input before processing the elements, whereas while(<>)
reads and processed the input line-by-line. That's because, according
to "perldoc perltrap", "while (<FH>)" is equivalent to:
while (defined($_ = <FH>))
So using for(<>) should work with small input, but be careful of large
inputs, or the entire file/input will be read in at once.
There is also another difference that is rather subtle, so it often
goes unnoticed: Because while(<>) implicitly assigns to the $_
variable, that variable WILL be different after the while-loop than
before the loop.
In contrast to the for-loop, for(<>) sets $_ to each entry of the
list that <> expands to, but the difference being that $_ will be
restored to whatever it was right before the for-loop was
encountered. (So for example, if $_ was "hello" before the for-loop,
it will be restored to "hello" when the for-loop is done.)
This is not so for while-loops. If $_ was "hello" right before the
while-loop, after the while-loop it will be set to the last line
returned from <> (accounting to any changes you make to $_ inside the
loop, of course).
The fact that for-loops restore $_ when they're finished looping
make it (usually) safe to nest them inside each each other, as even if
they all operate on $_, they'll restore the outer $_ when they're
done. I found out the hard way that while-loops don't do this, as
inner while-loops will readily "hijack" $_ without restoring them to
the value set by the outer while-loops.
So while(<>) generally uses less memory and is more efficient than
for(<>), but keep in mind that while-loops won't restore the original
value of $_ when they're done looping.
Cheers,
-- Jean-Luc