in reply to Re: Nested line buffered output
in thread Nested line buffered output

Okay, I can write two sample programs to illustrate my question.

p1.pl
#!/usr/bin/perl use strict; use warnings; $|=1; my $p2 = "/tmp/p2.pl"; open(P2,"$p2 |") || die "P2: $p2 - $!\n"; while(<P2>) { print; }
p2.pl
#!/usr/bin/perl use strict; use warnings; $|=1; my $i; for $i (1..10) { print "."; sleep 1; } print "\n";
The output of p2.pl is 1 dot every second for 10 seconds but the output of p1.p1 is 10 dots after 10 seconds. Thanks.

Replies are listed 'Best First'.
Re^3: Nested line buffered output
by mr_mischief (Monsignor) on Jun 01, 2010 at 18:31 UTC
    The problem is in the title: "line buffered". You're reading P2 line-by-line, but printing only one line total in p2.pl in the first place. Try this in p1.pl:
    #!/usr/bin/perl use strict; use warnings; $|=1; my $p2 = "./p2.pl"; open(P2,"$p2 |") || die "P2: $p2 - $!\n"; while( read( P2, $_, 1 ) ) { # fixed as per [ikegami]'s post below print; }

    BTW, you should probably be using a lexical filehandle, but given the short example I won't complain too loudly. ;-)

    Update: fixed bug in read as pointed out by ikegami in Re^4: Nested line buffered output.

      The fourth arg of read is wrong. It should be 0 or simply omitted.

      If you're going to read one character at a time, getc would be clearer. But I recommend reading all available data instead of one character at a time. You can do that using sysread since it returns all available data (up to the specified limit) as soon as any data is available.

        Thanks for pointing out the error.

        The distinctions among read, sysread, and getc are useful, but any of them serve to point out the issue in the original node. I used read specifically because it is more flexible than getc and does interact properly with buffering if there is any. That may be preferable in some situations, but sysread may be preferable if bypassing buffers is desired as a rule.

        As an aside, although there is for perl 5.10.1 and 5.12.0 a note at the bottom of the entry for sysread in the perldocs about UTF and characters, the documentation for read is clearer at a glance about handling characters and not just bytes. That's not anything against the function, and it will probably be fixed in the docs at some point. It's worth noting if you're pointing the function out to people in the meantime, though, because you might want to mention that note stuck at the bottom of the entry.