Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > how about for(<>){...} instead of while(<>){...}

Reply
Thread Tools

how about for(<>){...} instead of while(<>){...}

 
 
jidanni
Guest
Posts: n/a
 
      03-31-2011
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().
 
Reply With Quote
 
 
 
 
Randal L. Schwartz
Guest
Posts: n/a
 
      03-31-2011
>>>>> "jidanni" == jidanni <(E-Mail Removed)> writes:

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

Try this:

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

vs

@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.

Oops.

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
<(E-Mail Removed)> <URL:http://www.stonehenge.com/merlyn/>
Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.
See http://methodsandmessages.posterous.com/ for Smalltalk discussion
 
Reply With Quote
 
 
 
 
jl_post@hotmail.com
Guest
Posts: n/a
 
      03-31-2011
On Mar 30, 7:11*pm, jidanni <(E-Mail Removed)> wrote:
> 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
 
Reply With Quote
 
ilovelinux
Guest
Posts: n/a
 
      04-04-2011
On 31 mrt, 19:21, Jean-Luc <(E-Mail Removed)> wrote:
> * *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).


Not entirely correct.

while(<>) { }
is, as Jean-Luc correctly points out, equivalent to
while (defined($_=<>)) { }
and when this loop ends, $_ will be undefined.
 
Reply With Quote
 
jl_post@hotmail.com
Guest
Posts: n/a
 
      04-04-2011
On Apr 4, 6:04*am, ilovelinux <(E-Mail Removed)> wrote:
>
> while(<>) { }
> is, as *Jean-Luc correctly points out, equivalent to
> while (defined($_=<>)) { }
> and when this loop ends, $_ will be undefined.



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
undefined).

Thanks for pointing that out.

-- Jean-Luc
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
Why us T-bird instead of OE? Serious question. J Firefox 11 02-09-2005 10:42 AM
WindowsXP is using my Wireless card instead of my Wired Nic =?Utf-8?B?TWFydHk=?= Wireless Networking 2 12-30-2004 10:12 PM
Asking to download links instead of taking me to them. Gary Walker Firefox 3 12-25-2004 12:24 PM
pesky windows logo instead of firefox on scrollbar buggerbuggerbugger Firefox 7 08-09-2004 02:13 PM



Advertisments