How can I autoflush a Perl 6 filehande?

488 Views Asked by At

There are a couple of answers for Perl 6 back in its Parrot days and they don't seem to work currently:

This is Rakudo version 2017.04.3 built on MoarVM version 2017.04-53-g66c6dda implementing Perl 6.c.

The answer to Does perl6 enable “autoflush” by default? says it's enabled by default (but that was 2011).

Here's a program I was playing with:

$*ERR.say: "1. This is an error";
$*OUT.say: "2. This is standard out";

And its output, which is an unfortunate order:

2. This is standard out
1. This is an error

So maybe I need to turn it on. There's How could I disable autoflush? which mentions an autoflush method:

$*ERR.autoflush = True;
$*ERR.say: "1. This is an error";
$*OUT.say: "2. This is standard out";

But that doesn't work:

No such method 'autoflush' for invocant of type 'IO::Handle'

I guess I could fake this myself by making my IO class that flushes after every output. For what it's worth, it's the lack of this feature that prevented me from using Perl 6 for a particular task today.

As a secondary question, why doesn't Perl 6 have this now, especially when it looks like it used to have it? How would you persaude a Perl 5 person this isn't an issue?

4

There are 4 best solutions below

3
On BEST ANSWER

This might not have worked yet when you asked the question, but:

$*ERR.out-buffer = False;
$*ERR.say: "1. This is an error";
$*OUT.say: "2. This is standard out";

It's a bit hard to find, but it's documented here.

Works for me in Rakudo Star 2017.10.

1
On

If you're primarily interested in STDOUT and STDERR, the following seems to reopen them without buffering (auto-flushed):

$*OUT = $*OUT.open(:!buffer);
$*ERR = $*ERR.open(:!buffer);

This isn't thoroughly tested yet, and I'm surprised this works. It's a funny API that lets you re-open an open stream.

0
On

There was an output refactory very recently. With my local version of rakudo i can't get it to give the wrong order any more (2017.06-173-ga209082 built on MoarVM version 2017.06-48-g4bc916e)

There's now a :buffer argument to io handles that you can set to a number (or pass it as :!buffer) that will control this.

I assume the default if the output isatty is to not buffer.

2
On

Rakudo doesn't support autoflush (yet). There's a note in 5to6-perlvar under the $OUTPUT_AUTOFLUSH entry.

raiph posted a comment elsewhere with a #perl6 IRC log search showing that people keep recommending autoflush and some other people keep saying it's not implemented. Since it's not a documented method (although flush is), I suppose we'll have to live without for a bit.