gpt4 book ai didi

raku - Perl 6 的 eof 是否放弃得太快了?

转载 作者:行者123 更新时间:2023-12-05 01:06:04 27 4
gpt4 key购买 nike

在 Perl 5 中,我可以检查标准输入是否打开并从中读取一行。

for (;;) {
last if eof(STDIN);
print "Got line " . readline(STDIN);
}

当我运行它并输入一行输入时,它会读取该行并在继续之前完成其工作。程序不关心是否有长时间的停顿:
$ perl print-stdin.pl
this
Got line this
is
Got line is
a
Got line a
line
Got line line

如果我在 Perl 6 (Rakudo 2017.07) 中做同样的事情,程序会立即停止:
use v6;
loop {
last if $*IN.eof;
put "Got line " ~ $*IN.get;
}

我真的很喜欢 Supply这可以在它到达时给我一行输入(可能来自一个缓慢输出带有长时间停顿的行的程序)但我一直备份到这个简单的问题。我没有找到一种内置的方法来做到这一点(这对于这样一个常见的任务来说有点令人惊讶)。

最佳答案

它似乎在最新版本上效果更好。
尽管您编写的内容存在竞争条件,因为在调用 .eof 后可以关闭输入。 .这意味着它可能发生在 .get被阻塞,所以会返回 Nil .这将导致抛出警告,以及额外的 Got line 要打印。

最好只使用 .lines 中的迭代器

for $*IN.lines { put "Got line $_" }

或使用 .get 的返回值以确定何时关闭输入。

loop {
with $*IN.get {
put "Got line $_"
} else {
last
}
}

如果您想要来自输入行的 Supply:

$*IN.lines.Supply

react {
start whenever $*IN.lines.Supply {
put "Got line $_";
LAST done; # finish the outer 「react」 block when this closes
}
whenever Supply.interval(1) {
put DateTime.now.hh-mm-ss
}
}

22:46:33
22:46:34
a
Got line a
22:46:35
22:46:36
b
Got line b
22:46:37
22:46:38
c
Got line c
22:46:39
22:46:40
d
Got line d
22:46:41
22:46:42
^D # represents Ctrl+D
start上面需要,所以它不会阻止 Supply.interval(1)供应从正常启动。

如果由于某种原因无法实现上述操作,您可以创建这样的 Supply:

my \in-supply = supply {

# 「await start」 needed so this won't block other things on this thread.

await start loop {
with $*IN.get { # defined (so still open)

emit $_

} else { # not defined (closed)

done; # stop the Supply

# last # stop this loop (never reached)

}
}
}

react {
whenever in-supply {
put "Got line $_";
LAST done # finish the outer 「react」 block when this closes
}
whenever Supply.interval(1) {
put DateTime.now.hh-mm-ss
}
}

关于raku - Perl 6 的 eof 是否放弃得太快了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47046761/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com