Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

opening missing file inside eval statement

by Anonymous Monk
on Jan 08, 2011 at 20:42 UTC ( #881267=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks

why doesn't the following code create an error if the file can't be found inside an eval block

open(INFH, "<$file")
If i add a die statement then i can get the error message from the die statement like so
eval { open(INFH, "<$file") or die "can't find input file"; }; print "Error $@", "failed" if ($@);
But the error displayed is my custom error "can't find input file." I wanted to display the system error message but there doesn't seem to be one if you can't find the file when opening it (though you do get an error if you try and do anything with the file later). I was hoping i could put all my 'dangerous' code inside an eval block and this would catch all the system error messages for me. Is it just one of those things that perl lets you do - open a file handle on a non-existent file?

Would you do your error handling for this any differently? I think die statements all over the place diminish code readability myself


Replies are listed 'Best First'.
Re: opening missing file inside eval statement
by toolic (Bishop) on Jan 08, 2011 at 20:54 UTC
    Check the return (error) status of open with $! (Tip #7 from Basic debugging checklist).
    I think die statements all over the place diminish code readability myself
    autodie was created to address that issue.

    Re-writing your code with more modern/robust style:

    open my $fh, '<', $file or die "can't find input file $!";

      Just a personal preference on my part: I never put anything other than "$filename: $!\n" in the 'die' string - because it can lead to nonsense messages like this:

      test.txt: cannot find input file Is a directory test.txt: cannot find input file Permission denied


      Education is not the filling of a pail, but the lighting of a fire.
       -- W. B. Yeats
        Agreement, though I like to say "opening '$filename': $!\n". This way, I
        • know where the problem was (as opposed to writing or positioning the file)
        • can see if there's a null or CRLF terminated string as the filename.
Re: opening missing file inside eval statement
by Corion (Pope) on Jan 08, 2011 at 20:47 UTC

    You don't show us what you actually tried. The following works for me:

    if (! open INFH, "<$file") { warn "Error opening '$file': $!"; };
      this is exactly what i tried and perl didn't catch the error when the file was missing.
      open (INFH, "<$file") {
      I only got an error later when i tried to read from it.

        What you show is not even valid Perl (or when it is, it is a snippet, meaningless in itself). Either post the minimal exact code that produces the problem for you, so we can help you better by reproducing the error ourselves. Or run the code I posted above, and look at what output it produces.

Re: opening missing file inside eval statement
by GrandFather (Sage) on Jan 08, 2011 at 22:44 UTC

    To complement and obtain the full benefit of toolic's suggestion to use the three parameter version of open you should also use structures (use strict; use warnings;) which perform extra compile time and run time checking for you to alert you to problems sooner rather than later.

    True laziness is hard work
Re: opening missing file inside eval statement
by PeterPeiGuo (Hermit) on Jan 08, 2011 at 21:03 UTC

    This is basically perl's way of throwing exceptions. What you put in "die" is essentially your exception.

    It might be beneficial for open to throw exception in some cases, but that's not always the case. The fact that perl leaves it to you to decide whether to throw exception, makes things flexible.

    Peter (Guo) Pei

Re: opening missing file inside eval statement
by JavaFan (Canon) on Jan 09, 2011 at 18:54 UTC
    You seem to be assuming that Perl by default* dies if an open fails. It doesn't (and be glad it doesn't). As one of the creators of Unix said "not being able to open a file is not exceptional". Hence, in C, and therefore also in Perl, open doesn't die (nor throws an exception) if a file cannot be opened. Its return value tells you whether it succeeded or not.

    *But you can install autodie.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://881267]
Approved by toolic
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (2)
As of 2018-04-21 21:43 GMT
Find Nodes?
    Voting Booth?