Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re: File Reading and Closing confusion

by shmem (Canon)
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.

Erm...no. 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.


Comment on Re: File Reading and Closing confusion
Select or Download Code
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?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://853655]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (4)
As of 2015-07-05 08:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (61 votes), past polls