how about for(<>) instead of while(<>)

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View
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().

Re: how about for(<>) instead of while(<>)

jidanni> Gentlemen, what peril awaits me if I use
jidanni> for  (<>) loops instead of
jidanni> while(<>) loops?

Try this:

    @ARGV = qw(verylargefile);
    while (<>) { ... }


    @ARGV = qw(verylargefile);
    foreach (<>) { ... }

The first one has a line-at-a-time in memory, regardless of the size of
the file.  The second one *must* read the *entire file* into memory
before starting the foreach loop.


Yes, this is in Learning Perl.  I recommend you read Learning Perl if
you have questions at this level.

print "Just another Perl hacker,"; # the original

Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.
See for Smalltalk discussion

Re: how about for(<>) instead of while(<>)

Quoted text here. Click to load it

Using great gobs of RAM unnecessarily.

Tad McClellan
email: perl -le "print scalar reverse qq/moc.liamg0cm.j.dat/"
The above message is a Usenet post.
I don't recall having given anyone permission to use it on a Web site.

Re: how about for(<>) instead of while(<>)

Quoted text here. Click to load it

   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.


   -- Jean-Luc

Re: how about for(<>) instead of while(<>)

Quoted text here. Click to load it

Not entirely correct.

while(<>) { }
is, as  Jean-Luc correctly points out, equivalent to
while (defined($_=3D<>)) { }
and when this loop ends, $_ will be undefined.

Re: how about for(<>) instead of while(<>)

Quoted text here. Click to load it

   Oh, right... while(<>) breaks out once it sets $_ to undefined
(which is one iteration after $_ is set to the last line).

   Regardless, $_ won't be restored to the value it was when the
while(<>) loop was encountered (unless, of course, it was already

   Thanks for pointing that out.

   -- Jean-Luc

Site Timeline