http://www.perlmonks.org?node_id=1006738

bhargava_hemant7 has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks, I am wondering that how while loop works with filehandles?What algorithms it follows inside and how does it get to know that i am done reading to file? ( Eof .. ? )

while ( <FILEHANDLE> ) { print; }

Replies are listed 'Best First'.
Re: How does while works with filehandles?
by tobyink (Canon) on Dec 02, 2012 at 19:22 UTC

    Usually, while( EXPRESSION ) stops looping when the expression becomes false, but Perl has an exception to that rule: if the expression is just reading a line from a file (and perhaps assigning it to a variable), then it only stops looping when the expression is undefined (undefined is false of course, but there are certain values which are false but defined).

    This works in conjunction with the fact that reading a line from a file that has reached its end will return undef.

    Observe the difference:

    $ echo -n "0" | perl -E'while(<>) { say "GOT" }' GOT $ echo -n "0" | perl -E'while(<> and 1) { say "GOT" }' $

    The first one prints "GOT" even though it read a false value from STDIN. This is because the special "reading from a filehandle" version of while gets used. The second doesn't print "GOT". This is because the more complex expression forces while to use its standard behaviour.

    There is another interesting aspect of the reading-from-filehandle version of while: if you don't assign the line to a variable, it gets assigned to $_. This doesn't happen when you read from a filehandle normally - only within while. Observe:

    $ echo "Hello" | perl -E'while(<>){ print $_ }' Hello $ echo "Hello" | perl -E'<>; print $_' $

    So anyway, while (<$fh>) works out as being equivalent to:

    while (defined($_ = <$fh>))

    ... which (by design, not just by luck) happens to be the kind of loop most people usually want when they're reading from a file.

    I suppose the other thing that is worth mentioning is the special variable $/ which is used by readline (an thus by <$fh>) to determine the current line ending. By default it's "\n" but you can set it to anything else you like, including undef.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: How does while works with filehandles?
by rjt (Curate) on Dec 02, 2012 at 18:40 UTC

    Have a look at the examples in Perl I/O Operators. I'd recommend you read the entire section, but the most relevant snippets that most directly answer your question are probably:

    In scalar context, evaluating a filehandle in angle brackets yields the next line from that file (the newline, if any, included), or undef at end-of-file or on error.
    ...
    The following lines are equivalent:
    while (defined($_ = <STDIN>)) { print; } while ($_ = <STDIN>) { print; } while (<STDIN>) { print; } for (;<STDIN>;) { print; } print while defined($_ = <STDIN>); print while ($_ = <STDIN>); print while <STDIN>;
Re: How does while works with filehandles?
by Anonymous Monk on Dec 02, 2012 at 18:04 UTC
      Thanks for your quick reply. But any alternate answer? This seems to be cropping out my mind. Can you give an high level idea?

        Thanks for your quick reply. But any alternate answer? This seems to be cropping out my mind. Can you give an high level idea?

        Sure, here you go, perlintro, readline, perlvar#$_, print