Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I autoflush a Perl 6 filehande?

Tags:

io

autoflush

raku

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?

like image 756
brian d foy Avatar asked Jul 08 '17 15:07

brian d foy


4 Answers

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.

like image 197
timotimo Avatar answered Oct 23 '22 14:10

timotimo


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.

like image 4
mscha Avatar answered Oct 23 '22 15:10

mscha


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.

like image 3
brian d foy Avatar answered Oct 23 '22 15:10

brian d foy


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.

like image 1
piojo Avatar answered Oct 23 '22 16:10

piojo