0

New to perl (and language in general), and have gone so far as OPEN FH. A little confused about the following two scenarios (outputs are different, but I couldn't understand why the second one is "wrong").

script 1

#! usr/bin/perl
use warnings;
use strict;
open FILE, "example.txt" or die $!;
while (<FILE>) {
    print $_;
    }

script2

#! usr/bin/perl
use warnings;
use strict;
open FILE, "example.txt" or die $!;
my @array = <FILE>;
while (<FILE>) {
    print $_;
    }

The example.txt contains 3 lines of sentence. When I assign filehandle FILE to an array, suddenly, $_ becomes empty ??

If I replace <FILE> in the while loop with array (@array), the loop cannot stop and $_ becomes "uninitialized value".

This is likely a very basic misunderstanding of filehandle and array , but can someone please help explain them - in plain English - ? Or point to the references where I could find more info (have a few references handy and have consulted them, but obviously I still couldn't quite understand why script 2 (and 3) are not correct). Great many thanks.

B Chen
  • 923
  • 2
  • 12
  • 21
  • 2
    http://perlmaven.com/reading-from-a-file-in-scalar-and-list-context – mpapec Jun 06 '15 at 03:02
  • thanks a lot for showing perlmaven !! – B Chen Jun 06 '15 at 03:18
  • Looks like Сухой27 solved your issue, but I want to point out that in Perl, it's a common idiom to use the three-arg open: open my $fh, '<', 'file.txt' or die "Can't open file: $!"; – stevieb Jun 06 '15 at 03:27
  • thanks for pointing it out. i saw that idiom in oreilly's books, but somehow the "beginner book" (non-oreilly, I assume) did not follow that idiom. the program still runs without the traditional idiom but now i wonder if reading the beginner book is the right choice ?? – B Chen Jun 06 '15 at 10:32

1 Answers1

2

In Perl, when you read from a filehandle in a list context, it automatically reads to the end of the file. $_ is empty because the entire file has been read into @array, and the filehandle has been moved to EOF. Perl's different handling of the same instruction in scalar and list "context" is unusual, but the behavior of the filehandle itself is pretty standard across languages. In general, a filehandle or input stream will let you read a line at a time, a byte at a time, or the whole file at a time, and have a pointer that keeps track of the last place in the file you read. When you inadvertently moved that pointer all the way to the end of the file (EOF) by doing a read in a list context, your next call to read a line finds that there's no more file to read. This is a pretty good explanation of scalar and list context; that might be the trickier part of what's going on here.

Kevin
  • 5,874
  • 3
  • 28
  • 35