Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

•Re: You *Can* Catch errors in closing lexical filehandles

by merlyn (Sage)
on Sep 27, 2004 at 17:52 UTC ( [id://394264]=note: print w/replies, xml ) Need Help??


in reply to You *Can* Catch errors in closing lexical filehandles
in thread Catching errors in closing lexical filehandles

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.

  • Comment on •Re: You *Can* Catch errors in closing lexical filehandles

Replies are listed 'Best First'.
Re^2: You *Can* Catch errors in closing lexical filehandles
by ihb (Deacon) on Sep 27, 2004 at 18:17 UTC

    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.

        And I just verified that 5.8.5 doesn't unset the variables, so it works as it always has.

        Ah, indeed. I forgot that I've also tried it with the same result as you. I brought it up on freenode #perl. I considered it a bug and I still do. It's either a documentation bug or a perl bug. I don't think the documentation can be interpreted as you suggest. It clearly says "if the match fails".

        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.

        That's the behaviour I get for perl version 5.005_03 built for sun4-solaris. I interpret the "more consistently" part as a mismatch unsets all, since that behaviour would be more consistant with how it already works when $3 .. $6 is unset/not matched; failing a match would mean "you didn't match $1 .. $n so it should be unset". Whether or not the behaviour is more consistant I won't argue over, but this is how I interpret the documentation.

        I assumed this behaviour change was due to some considering that the values in the regex variables after a failed match are "false data", as the documentation calls it. I assumed it was an attempt to make Perl DWIM, for some definition of I.

        ihb

        Read argumentation in its context!

Re^2: You *Can* Catch errors in closing lexical filehandles
by Zaxo (Archbishop) on Sep 27, 2004 at 22:53 UTC

    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

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (4)
As of 2024-03-29 15:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found