Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl: Unexpected $_ behaviour

Tags:

perl

use Modern::Perl;
use DateTime;
use autodie;

my $dt;

open my $fh, '<', 'data.txt';

# get the first date from the file
while (<$fh> && !$dt) {
   if ( /^(\d+:\d+:\d+)/ ) {
      $dt = DateTime->new( ... );
   }
   print;
}

I was expecting this loop to read each line of the file until the first datetime value is read.

Instead $_ is unitialised and i get a load of "uninitialized value $_ in pattern match" ( and print ) messages.

Any ideas why this happens?

A

like image 853
Richard Avatar asked Mar 27 '12 12:03

Richard


1 Answers

$_ is only set if you use the form while (<$fh>) form, which you are not.

Look at this:

$ cat t.pl
while (<$fh>) { }
while (<$fh> && !$dt) { }

$ perl -MO=Deparse t.pl
while (defined($_ = <$fh>)) {
    ();
}
while (<$fh> and not $dt) {
    ();
}
t.pl syntax OK

From the perlop docs:

Ordinarily you must assign the returned value to a variable, but there is one situation where an automatic assignment happens. If and only if the input symbol is the only thing inside the conditional of a while statement (even if disguised as a for(;;) loop), the value is automatically assigned to the global variable $_, destroying whatever was there previously.

like image 114
Mat Avatar answered Sep 20 '22 15:09

Mat