Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

You *Can* Catch errors in closing lexical filehandles

by Zaxo (Archbishop)
on Sep 27, 2004 at 15:17 UTC ( [id://394196]=note: print w/replies, xml ) Need Help??


in reply to Catching errors in closing lexical filehandles

I have no idea why eval drops this instead of converting to $@, but you can check $! after a block exit.

$ perl -e'eval{open my $fh, ">", "/dev/full"; print $fh "Foo\n";}; pri +nt $!' No space left on device
It would be wise to clear $! beforehand so you don't see leftovers.
use Fatal qw/open close/; { $! = undef; open my $fh, '>', '/dev/full'; print $fh 'short text' or die $!; } die $! if $!;

After Compline,
Zaxo

Replies are listed 'Best First'.
•Re: You *Can* Catch errors in closing lexical filehandles
by merlyn (Sage) on Sep 27, 2004 at 17:52 UTC
    The rule:
    Never use $! unless you've recently checked for an O/S request failure.
    This is akin to the rule:
    Never use $1 (and friends) unless you've recently checked for a match success.
    because both share the same principle: these variables are set, but never reset. So you might be looking at stale results.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      As of Perl 5.7.0 this behaviour has changed for $1 and friends. From perl570delta:

      The regular expression captured submatches ($1, $2, ...) are now more consistently unset if the match fails, instead of leaving false data lying around in them.

      ihb

      Read argumentation in its context!

        The regular expression captured submatches ($1, $2, ...) are now more consistently unset if the match fails, instead of leaving false data lying around in them.
        I believe this is referring to the fact that if a match has $1..$6 in one successful match, then only $1..$2 in the next match, that $3..$6 are more carefully set to undef now. I remember there being a patch to that effect.

        If they were to change the other behavior, it would no longer be (usefully) upward compatible. This would have been a grave mistake, caught by someone (like me).

        The reason the variables are not unset on failure is to permit:

        if ($string = /... ( ... ) .../) { # overall match if ($1 =~ /foo/) { # and $1 contains foo ... } elsif ($1 =~ /bar/) { # nope? how about bar ... } }
        If $1 reset on the failed match on the second line, then we couldn't do the third match. This has been by design in Perl for over a decade now. (And I just verified that 5.8.5 doesn't unset the variables, so it works as it always has.)

        -- Randal L. Schwartz, Perl hacker
        Be sure to read my standard disclaimer if this is a reply.

      Exactly, that's why I mentioned stale values of $! and set it to undef in the scriptified version of the second paragraph.

      It would have been better to do that right before exiting the scope of $fh. EAGAIN is sometimes possible during normal I/O.

      After Compline,
      Zaxo

Re: You *Can* Catch errors in closing lexical filehandles
by Anonymous Monk on Sep 27, 2004 at 15:53 UTC
    eval would only "drop" something and populat $@ if something went wrong - that is, a "die" or a fatal error. But in the code you give, nothing goes wrong. Sure, print() and the implicite close() might return false values, but that doesn't mean the code dies. Hence, $@ will be undefined.

    Beside that, I wouldn't use this construct. Sure, it might be safe in this simple case, but in general, you might have more code in the block. Which means that upon termination of the block, end-of-scope actions will be run. Lexical variables will go out of scope, DESTROY blocks might be run, and local variables will get their old values back. This might cause all kinds of library calls to happen, each of which might set $! (even if they succeed!)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (5)
As of 2024-03-29 11:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found