如何解决在 Raku 中使用 get/prompt 进行 gettig 后,如何清除 stdin ($*IN) 上的 EOF?
在我的程序中,我想循环读取 $*IN
中的一行,为此我可以使用 get
或 prompt
;然而,我注意到,如果我立即用 EOF 结束我的输入(例如,在 Linux / MacOS 中用 Ctrl-D)那么任何后续使用 get
或 prompt
来读取来自 {{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 举报,一经查实,本站将立刻删除。