in reply to Re^6: Best way to handle readline errors?
in thread Best way to handle readline errors?

In the case of EOF, $! (or errno) is not modified and will have the value it had before readline was called, since the system call(s) have not failed.

That's wrong, according to the docs for $!. The value of $! is undefined if no error has occured. You cannot count on it being unchanged.

Furthermore, it's observably wrong on my system. $! does not remain unchanged after EOF, or even after reading a line successfully.

To answer your earlier question, yes, readline is wrong.

Replies are listed 'Best First'.
Re^8: Best way to handle readline errors?
by jrw (Monk) on Nov 29, 2006 at 17:10 UTC
    Well, if you ran my test program (see above) on unix and got different results than I did, then I will have to defer to an observable fact that different versions of perl handle this differently. But on all the unix machines I've tested this on, it is 100% consistent (I will concede that Windows perl handles this differently).

    Plus, the docs for $! state "after a failure". There is no definition for "failure" given, but I assume it means after readline returns undef, which it does on both EOF and I/O error. Therefore, it is valid to check the value of $! in the case under consideration, since readline has returned undef.

    Could you please post the output of "uname -a" on the version of unix where you ran my test program and the version of perl you used to run it? Here are my results for a variety of perl versions and unices, plus Windows XP. The only version that displays the strange behavior of modifying $! on EOF is Windows XP.

      Plus, the docs for $! state "after a failure". There is no definition for "failure" given

      The docs are clear. $! is either set or it's value is meanlingless. Both the docs for the read system call and your own observations show that $! doesn't get set on EOF.

      You could say the docs for readline override the docs for $!, but that's obviously not true.

      If you don't care about portability, and you think it's safe enough for you, it's your call. Be sure to pick a value for $! that doesn't correspond to a valid errno on your system. Zero is probably a bad pick.

      Could you please post the output of "uname -a" on the version of unix where you ran my test program

      I'm using various versions of Perl on various versions of Windows.

        My belief is that, on unix, $! mirrors errno exactly. And on unix, errno behaves the way I have described. It is modified (to a non-zero value) by failing system calls and not modified by successful ones. Therefore, on unix, setting $! to zero before making a call to a perl function which (may) make a system call is a valid way of checking for an error.

        Can anyone explain why Windows perl behaves as it does, and not like unix, in this respect?

        In any case, using readline on Windows seems like a very iffy proposition if you're doing any serious programming which requires tight error checking. I wish that weren't so, because readline certainly is convenient.

Re^8: Best way to handle readline errors?
by jrw (Monk) on Nov 29, 2006 at 17:13 UTC
    Since Windows perl (ActiveState) does modify $! on both EOF and I/O error, how can those two cases be distinguished (i.e. when readline returns undef)?

      Perl does not provide a mechanism to check if readline returned an error. Wasn't this thread about finding one? My earlier posts show that I didn't find one.

        It'd be nice if <> returned '' for EOF and undef for error. Even implementing that in a backward-compatible way would be tricky (a pragma that turns on that behavior within a lexical scope and teaching while(<>) to deal with it -- or making this change in Perl 6).

        - tye        

        Actually, this thread is about the best way to handle errors, not whether or not there is a way. I assumed the readline doc is correct. In my experience on unix, it is. I can't explain why Windows perl behaves as it does, but there is a lot I can't explain about Windows.