Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Re: File Reading and Closing confusion

by shmem (Chancellor)
on Aug 08, 2010 at 14:17 UTC ( #853655=note: print w/replies, xml ) Need Help??

in reply to File Reading and Closing confusion

and that the second case might warrant undefing the variable $/ and then maybe splitting or doing array manipulation. You undefine $/ to slurp a file into a scalar; whereas @array = <FH> populates @array with lines, trailing $/ chopped off implicitly or not, according to the command line switch -l (update: wrong, implicit chomp only happens in combination of l with the n or p switch).

What I am confused about is when in a loop I have something like while(<FH>){...}, is this any different than $line=<FH> or are these granularly the same?

Run perldoc -f readline. That said, no, those are not the same: while(<FH>){...} assigns to $_, but $line=<FH> assigns to $line. Other than that, they are the same.

To delete a file we use unlink and to close a file handle we use close and then we have undef which can also close a filehandle for us, my heart tells me that using undef this way is somewhat frowned upon or sinful, is that justified?

That's not frowned upon or sinful, since a common idiom is

my @lines = do { open my $fh, '<', $file or die "$file: $!\n"; <$fh> } +;

Perl scoping rules apply. As can be seen reading open, file handles are closed if they get out of scope (and are thus undefined implicitly). So, nothing wrong about undef $fh.

One caveat, though: You might encounter problems closing a file handle - for example flushing buffers and closing a file residing on a remote mountpoint, which became unavailable during operation of your program.

So, it is always wise to close your file handles explicitly and check the return value.

Replies are listed 'Best First'.
Re^2: File Reading and Closing confusion
by repellent (Priest) on Aug 08, 2010 at 23:31 UTC
      That said, no, those are not the same: while(<FH>){...} assigns to $_, but $line=<FH> assigns to $line. Other than that, they are the same.

    Actually, a crucial difference is that while(<FH>){...} gets interpreted by Perl as:
    while (defined($_ = <FH>)) { ... }

    which effectively ends the while loop once there are no more lines to be read from the filehandle. With $line=<FH>, we need to check for defined-ness.

      my @lines = do { open my $fh, '<', $file or die "$file: $!\n"; <$fh> };

    Another way:
    my @lines = do { local @ARGV = $file; <> };
      With $line=<FH>, we need to check for defined-ness.

      No. While there are lines read, they are defined since they have $/ attached. If $/ is undef, no point for while, since that's slurp mode. An empty string on the last line with no $/ is - no line.

        I was referring to being wary when $line=<FH> is used on its own. To illustrate:
        $ perl -e 'print "with_ending\nno_ending"' > a.txt $ perl -MData::Dumper open(FH, "<", "a.txt") or die $!; my $line1 = <FH>; my $line2 = <FH>; my $line3 = <FH>; close FH; $Data::Dumper::Useqq = 1; print Dumper [$line1, $line2, $line3]; __END__ $VAR1 = [ "with_ending\n", "no_end", undef ];

        We see that there is a possibility that a line read ($line3 in this case) may return undef. That's what I meant: we need to be wary that a line read will not always return defined.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://853655]
[Corion]: At least back in the day Firefox (well, Netscape) used to cache the DNS itself because there was no OS API to asynchronously resolve names (?) Maybe that code still lives on
[Corion]: Mhmm. Our datawarehouse is named after the department, except that the department changed its name one year ago. Now I guess I'm looking for the moral equivalent of "THE Datawarehouse", where "THE" stands for "Traditional High-valued Expertise" ;)

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (8)
As of 2017-07-26 08:40 GMT
Find Nodes?
    Voting Booth?
    I came, I saw, I ...

    Results (386 votes). Check out past polls.