【问题标题】:How can I autoflush a Perl 6 filehande?如何自动刷新 Perl 6 文件处理?
【发布时间】:2017-12-12 17:47:42
【问题描述】:

在 Parrot 时代有几个 Perl 6 的答案,但它们目前似乎不起作用:

这是基于 MoarVM 版本 2017.04-53-g66c6dda 构建的 Rakudo 版本 2017.04.3 实现 Perl 6.c.

Does perl6 enable “autoflush” by default? 的答案是默认启用(但那是 2011 年)。

这是我正在玩的一个程序:

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

及其输出,这是一个不幸的命令:

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

所以也许我需要打开它。 How could I disable autoflush? 提到了 autoflush 方法:

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

但这不起作用:

对于“IO::Handle”类型的调用者没有这种方法“autoflush”

我想我可以通过让我的 IO 类在每次输出后刷新来自己伪造这个。就其价值而言,正是缺少此功能使我无法将 Perl 6 用于今天的特定任务。

作为第二个问题,为什么 Perl 6 现在没有这个,尤其是当它看起来像以前有的时候?你如何说服 Perl 5 的人这不是问题?

【问题讨论】:

    标签: io raku autoflush


    【解决方案1】:

    当你问这个问题时,这可能还没有奏效,但是:

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

    有点难找,但记录在案的 here

    在 Rakudo Star 2017.10 中为我工作。

    【讨论】:

    • FWIW TTY 句柄没有缓冲,不需要设置。 OP 观察到的行为是由于 2017.04 仍然使用 libuv 的异步 IO 进行输出。
    • $*ERR.out-buffer$*OUT.out-buffer 设置为False 在您的输出被重定向或管道传输(例如2>&1 | less)时仍然有用。
    • 这与 autoflush 几乎不一样......无缓冲的流在每个字节后有效地刷新,而 autoflush 在每次写入或打印后刷新,这通常要快得多。
    【解决方案2】:

    如果您主要对 STDOUT 和 STDERR 感兴趣,以下似乎可以在不缓冲的情况下重新打开它们(自动刷新):

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

    这还没有经过彻底的测试,我很惊讶它的工作原理。这是一个有趣的 API,可让您重新打开打开的流。

    【讨论】:

    • 无缓冲不等于自动刷新。
    【解决方案3】:

    最近有一个输出重构。使用我的本地版本的 rakudo,我无法再让它给出错误的命令 (2017.06-173-ga209082 built on MoarVM version 2017.06-48-g4bc916e)

    现在 io 句柄有一个 :buffer 参数,您可以将其设置为一个数字(或将其作为 :!buffer 传递)来控制它。

    如果输出 isatty 不缓冲,我假设默认值。

    【讨论】:

      【解决方案4】:

      Rakudo 不支持自动刷新(目前)。在$OUTPUT_AUTOFLUSH 条目下的5to6-perlvar 中有一条注释。

      raiph 用#perl6 IRC log search 在其他地方发表了评论,表明人们一直在推荐 autoflush,而其他一些人一直在说它没有实现。由于它不是一个记录在案的方法(尽管flush 是),我想我们将不得不暂时没有。

      【讨论】:

      • 这是一个简单但不能令人满意的答案,但我添加了一个次要问题,询问我们为什么没有它。如果您有基本原理或技术限制细节,我认为这对人们有用。
      • 文档用错了(现在是amended)。不是 autoflush 没有实现,而是 buffering 没有实现(以及扩展的 autoflush)。我怀疑您看到的行为是因为我们曾经在后端使用异步 IO,即使在前端同步 IO 也是如此。该部分现在(自 2017.06 起)已同步。此外,目前正在进行添加缓冲的实验性工作,可能使用 open:buffer 参数(当前默认关闭,以后可能会默认启用)。
      猜你喜欢
      • 1970-01-01
      • 2011-03-09
      • 1970-01-01
      • 2013-06-24
      • 2013-06-24
      • 1970-01-01
      • 2022-01-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多