cow*_*moo 9 stdin get prompt eof raku
在我的程序中,我想从$*IN循环中读取一行,为此我可以使用get或prompt; 但是,我注意到如果我立即用 EOF 结束我的输入(例如,在 Linux/MacOS 中用 Ctrl-D),那么任何后续使用get或prompt读取另一行 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
根据这个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(我不知道为什么,看起来这可能是一个错误)