微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Raku 中使用 get/prompt 进行 gettig 后,如何清除 stdin ($*IN) 上的 EOF?

如何解决在 Raku 中使用 get/prompt 进行 gettig 后,如何清除 stdin ($*IN) 上的 EOF?

在我的程序中,我想循环读取 $*IN 中的一行,为此我可以使用 getprompt;然而,我注意到,如果我立即用 EOF 结束我的输入(例如,在 Linux / MacOS 中用 Ctrl-D)那么任何后续使用 getprompt 来读取来自 {{1} 的另一行} 将导致它返回 $*IN,这意味着它仍然从 Nil 获得 EOF。

示例:

$*IN

立即执行 EOF (ctrl-d),程序结束并输出两个 dd get; dd get;

如果输入的内容不仅仅是 EOF,则不会发生此问题。

奇怪的是,Nil 也不会出现这个问题。即,

slurp

在第一个 ctrl-d 之后,dd slurp; dd slurp; 由第一个 "" 打印,然后由于第二个 dd 而等待输入。

我认为这也是他们同样的问题 - https://github.com/rakudo/rakudo/issues/4196

解决方法

根据 this Perl 5 answer,您可以在收到 EOF 后通过打开 /dev/tty 重新打开 STDIN:

use v6;
print "Input line: ";
my $line = get;
if ($line === Any) {
    say "got EOF..";
    say "Reopening STDIN..";
    my $fh = open "/dev/tty",:r,chomp => $*IN.chomp,nl-in => $*IN.nl-in,encoding => $*IN.encoding;
    print "Enter new line: ";
    my $line = $fh.get();
    say "Got line: {$line}";
}
else {
    say "Not EOF,got line: {$line}";
}

以上有效,但我不确定如何将重新打开的 STDIN 句柄重新分配给 $*IN..

我尝试了以下方法:

$*IN = IO::Handle.new(path => IO::Path.new("/dev/tty"),encoding => $*IN.encoding);

但它没有重新打开 $*IN..

编辑

我也试过:

print "Input line: ";
my $line = get;
if ($line === Any) {
    say "got EOF..";
    say "Reopening STDIN..";
    $*IN.close;
    $*IN = open "/dev/tty",encoding => $*IN.encoding;
    my $line = get;
    say "Got line: {$line}";
}
else {
    say "Not EOF,got line: {$line}";
}

但是没有用:

Input line: got EOF..
Reopening STDIN..
Cannot do 'get' on a handle in binary mode
  in block <unit> at ./11.raku line 12

编辑 2

我想我发现了问题,在上面的脚本中你必须使用 my $line = $*IN.get 而不是 my $line = get(我不知道为什么,看起来它可能是一个错误)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。