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?
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With