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

cow*_*moo 9 stdin get prompt eof raku

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

例子:

dd get;
dd get;
Run Code Online (Sandbox Code Playgroud)

使用立即 EOF (ctrl-d),程序结束并输出 2 Nil

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

奇怪的是,这个问题也不会发生在slurp. IE,

dd slurp;
dd slurp;
Run Code Online (Sandbox Code Playgroud)

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

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

Håk*_*and 5

根据这个Perl 5 答案,您可以在收到 EOF 后重新打开 STDIN,方法是打开/dev/tty

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}";
}
Run Code Online (Sandbox Code Playgroud)

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

我尝试了以下方法:

$*IN = IO::Handle.new(path => IO::Path.new("/dev/tty"), :r,
                        chomp => $*IN.chomp, nl-in => $*IN.nl-in,
                        encoding => $*IN.encoding);
Run Code Online (Sandbox Code Playgroud)

但没有重新开放$*IN..

编辑

我也尝试过:

print "Input line: ";
my $line = get;
if ($line === Any) {
    say "got EOF..";
    say "Reopening STDIN..";
    $*IN.close;
    $*IN = open "/dev/tty", :r, chomp => $*IN.chomp, nl-in => $*IN.nl-in,
        encoding => $*IN.encoding;
    my $line = get;
    say "Got line: {$line}";
}
else {
    say "Not EOF, got line: {$line}";
}
Run Code Online (Sandbox Code Playgroud)

但它不起作用:

Input line: got EOF..
Reopening STDIN..
Cannot do 'get' on a handle in binary mode
  in block <unit> at ./11.raku line 12
Run Code Online (Sandbox Code Playgroud)

编辑2

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