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

Cheers all,

I recently stumbled over $subject -

for $foo ('a'..'c') { open FH,'|-', 'cat -'; select FH; for $bar (1..rand 10) { write } $- = 0; close FH; } format FH_TOP = =@= $foo . format FH = @ $bar . __END__ =a= 1 2 3 4 5 1 2 3 4 5 1 2

switching the lines with the $- assignment and close yields

for $foo ('a'..'c') { open FH,'|-', 'cat -'; select FH; for $bar (1..rand 10) { write } close FH; $- = 0; } format FH_TOP = =@= $foo . format FH = @ $bar . __END__ =a= 1 2 3 4 =b= 1 2 =c= 1 2

If the filehandle is pristine, $- is 0. But after the first close it is set to $= (page length), thus write skips format TOP.

In the source, in Perl_do_close() in doio.c (thanks mtve for pointing to it):

if (not_implicit) { IoLINES(io) = 0; IoPAGE(io) = 0; IoLINES_LEFT(io) = IoPAGE_LEN(io); }

Why?

It's not documented either. Anybody knows the rationale for that? - I know, that's an old corner of perl. I just want to know.

Replies are listed 'Best First'.
Re: close() resets $- to $=, not 0 (git)
by tye (Sage) on Feb 14, 2014 at 02:29 UTC

    That originated as a change from:

    if (explicit) stio->lines = 0;

    to:

    if (explicit) { io->lines = 0; io->page = 0; io->lines_left = io->page_len; }

    made public as:

    commit 79072805bf63abe5b5978b5928ab00d360ea3e7f Author: Larry Wall <lwall@netlabs.com> Date: Thu Oct 7 23:00:00 1993 +0000 perl 5.0 alpha 2 [editor's note: from history.perl.org. The sparc executables originally included in the distribution are not in this commit.] 433 files changed, -41401 +64754 lines

    You could search for a usenet report of some bug relatively soon before that timestamp.

    Resetting $- on explicit close certainly "makes sense". Depending on your particular use case, I can also see it making sense to skip TOP after an explicit close() and then re-use of the same file handle.

    - tye        

      shmem waited very patiently for that answer!

      use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name