Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

When <> fails

by Dinosaur (Beadle)
on Jul 29, 2008 at 19:20 UTC ( [id://700900]=perlquestion: print w/replies, xml ) Need Help??

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

A script which has been generally well behaved failed silently recently when nfs jerked the rug out from under its input file, which it had been reading with "while(<>)". Apparently <> just returned null when the error occurred, and the loop terminated gracefully.

Opening a filehandle and checking the return from close would get me around this problem. But the management of input files provided by <> is very convenient.

Is there any way to check the success of <>?

Thanks,

Dinosaur

Replies are listed 'Best First'.
Re: When <> fails
by betterworld (Curate) on Jul 29, 2008 at 19:44 UTC
    From perldoc -f readline:
    If readline encounters an operating system error, $! will be set with the corresponding error message. It can be helpful to check $! when you are reading from filehandles you don't trust, such as a tty or a socket. The following example uses the operator form of "readline", and takes the necessary steps to ensure that "readline" was successful. for (;;) { undef $!; unless (defined( $line = <> )) { die $! if $!; last; # reached EOF } # ... }
    I think "filehandles you don't trust" should be interpreted as all filehandles where a read might fail, especially when reading from a special device or something like that.
Re: When <> fails
by pc88mxer (Vicar) on Jul 29, 2008 at 19:32 UTC
    The current file handle that <> is using is stored in ARGV, but my testing shows that perl has alrady closed ARGV when the while (<>) {...} loop terminates.

    You might try checking $! to see if that gets set when the NFS server stops serving the file:

    while (<>) { ... } # check $! which is probably from the last close
    Update: ikegami pointed out that testing $! (as in if ($!) ... doesn't make sense here.

    One issue is that $! is only set when there is an error. One way around this is to force a known error at the end of the loop so that you can tell if readline generated an error.

    Update 2: One can assign to $!, so this should be able to detect if readline failed:

    while (<>) { ... $! = undef; } if (defined($!)) { # $! contains error from last <c>close
    } </c>
Re: When <> fails
by repellent (Priest) on Jul 30, 2008 at 01:16 UTC
    While I think that suggestions by pc88mxer and betterworld are the way to go, I can't help but wonder about the philosophical aspects of the issue :)

    All scripts make certain base assumptions in order to function. A stable filesystem to act on is a good base assumption. If NFS is erratic, there's not much the script can do in terms of handling that kind of catastrophic failure. The partial damage would have already occurred in previous while (<>) iterations, anyway.

    So, would it be useful to put out a warning that an unexpected critical error has just happened? Yes, that would be nice. But how far do we go?

    Will this succeed as a new Perl idiom:
    while (<>) { unless ($!) { # do actual stuff here } }
    How far do we go down the path of paranoia just to make the script bullet-proof?

    Update: Thanks for pointing my mistake out, ikegami. Still, I'd like to know how much is too much when it comes to error checking of this nature.

      That snippet makes no sense.

      • <> returns undef on error, so checking for an error in the loop is nonsense.
      • A true $! doesn't mean an error occured.
      • A false $! doesn't mean no error occured.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://700900]
Approved by Corion
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (4)
As of 2024-04-26 04:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found