2017-11-01 12 views
4

Perl 5では、標準入力が開いているかどうかを確認し、そこから1行を読むことができます。Perl 6のeofはあまりにも早くあきらめますか?

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の(2017.07 Rakudo)で同じことを行う場合は、プログラムがすぐに停止します:

use v6; 
loop { 
    last if $*IN.eof; 
    put "Got line " ~ $*IN.get; 
    } 

私は後に本当によ長い一時停止がある場合、プログラムは気にしません。 Supply私はそれが到着すると(私はおそらく長い休止を持つ行を出力するプログラムから)私は入力の1行を与えることができますが、私はこの単純な問題のすべての方法をバックアップしました。私はこれを行うための組み込みの方法を見つけられませんでした(これは、このような一般的な作業では少し驚きです)。

答えて

2

最新の方がうまくいくようです。
.eofの呼び出し後に入力を閉じることができるため、書いた内容に競合条件があります。つまり、.getがブロックされている間に起こる可能性があるので、Nilを返します。これにより、警告がスローされ、余分なGot line が印刷されます。

それはちょうど.lines

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

からIteratorを使用するか、入力が閉じているときを決定する.getの戻り値を使用することをお勧めします。

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

あなたは、入力ラインからの供給が必要な場合:

$*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 

それはからSupply.interval(1)の供給を遮断しないようにstartは、上記必要とされています正しく始まります。私はまだ `eof`で何が起こっているか知りたいのです

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 
    } 
} 
+0


は、上記のは、あなたがこのような供給を作成することができ、いくつかの理由では不可能であった場合。 –

+0

@briandfoy '.eof'は、' .eof'が呼び出された(ノンブロッキング)瞬間に入力がファイルの最後にある場合にTrueを返します。それが閉じられるまで、TTY上でeofに到達するかどうかを知る方法はありません。 '.get'は' \ r'' \ r \ n' '\ n'等やファイルの終わりまでブロックします。つまり、TTYは '.get'への呼び出しの間にミリ秒よりも' .get'への呼び出しの間に閉じられる可能性が高くなります。基本的に '.eof'を使ってはいけません。 (私は少なくとも5年前にPerl 5を使ってこれを学んだことがありますが、そこに問題はありません) –

+0

はい、TTYの場合、TTYが閉じられるまでeofがTrueを返さないと思います。 –

関連する問題