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

What does the line <FILE>; exactly do? $_ = <FILE>; and the former seems to have swapped meaning since the latter doesn't work at all. It all started with trying to do this:
my ($parent, $createtime) = split(/;/, <FILE>);
But that didn't work so I tried
$_ = <FILE>; my ($parent, $createtime) = split(/;/);
Neither did that but finally
<FILE>; my ($parent, $createtime) = split(/;/);
worked. Why did the first one not work and what's the deal with $_ and filehandles?

Another thing I don't understand is how
while (<FILE>) {$somevar .= $_} works but
while ($somevar .= <FILE>) {} doesn't. (It puts the program in a scary infinite loop)

Replies are listed 'Best First'.
Re: $_ and filehandles
by davido (Cardinal) on Aug 27, 2005 at 15:50 UTC

    Please get out of the habit of using expressions such as "...doesn't work." We need specifics. Doesn't work can mean a lot of things. I maintain that it does work according to defined behavior. It simply doesn't do what you expect, being unfamiliar with defined behavior.

    To see an explanation of what behavior is defined for the <diamond> operator, see perlop: IO Operators. There's good info there dealing with how the diamond operator and $_ interact.

    As for your question regarding the difference between:

    while (<FILE>) {$somevar .= $_} works but while ($somevar .= <FILE>) {} doesn't. (It puts the program in a scary + infinite loop)

    The first "works" because it's the right way to do things. The second puts the program into an infinate loop (Thank-you for describing what "doesn't work" means in this case) because 'while()' tests for truth. Once $somevar receives some value from <FILE>, and all future values from <FILE> are simply appended to $somevar, $somevar will always contain a value. Unless your file consists of nothing but zeros, that value will be true, so the loop will always evaluate truth, and thus will never exit. Note that...

    while( 1 ) { # do something }

    ... will never exit either.


    Dave

    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: $_ and filehandles
by sk (Curate) on Aug 27, 2005 at 16:38 UTC
    We sort of understand what you are trying to do but assumption is the root cause for many evils. We have no idea what you know and what you don't to make a good reply. That's exactly why davido asked you to stay away from "Does not work" statements

    Sample data (whatever is reqd to demonstrate the issue) and code that can be run to produce the problem will be much better.

    If you had known that <FILE>; will populate $_ when used as while() conditional and not when it is called by itself the response would have been totally different as you are seeing something unexpected.

    Going back to your question -

    If i do this i get expected output

    #!/usr/bin/perl use strict; use warnings; my ($field1,$field2) = (); $_ = <DATA>; ($field1, $field2) = split(/;/); print $field1,",",$field2; __DATA__ hi;there

    output:

    hi,there

    Please note that playing around with $_ requires caution. check out perldoc perlvar and search for nasty_break().

    cheers

    SK

Re: $_ and filehandles
by CountZero (Bishop) on Aug 27, 2005 at 19:05 UTC
    What do you expect my ($parent, $createtime) = split(/;/, <FILE>); to do? It splits the line read by <FILE> on ; and puts the first part in $parent and the second part in $createtime.

    If it doesn't do that I suggest that you check your input, perhaps the lines are empty or do not contain a ;?

    CountZero

    "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

Re: $_ and filehandles
by halley (Prior) on Aug 28, 2005 at 01:03 UTC
    The following two lines are equivalent:
    while (<FILE>) { ... } while (defined ($_ = <FILE>)) { ... }
    This is not at all intuitive, but this magical short form of while() saves a lot of typing for a kind of loop which is implemented very often. If you type ANY other kind of while() loop condition, then there is no special magic anymore, and it will just use what you typed. The code <FILE> by itself doesn't assign to $_ or anything else; it's only in the magical while() that you get the assignment for free.

    --
    [ e d @ h a l l e y . c c ]

    A reply falls below the community's threshold of quality. You may see it by logging in.