Perl6:检查 STDIN 是否有数据 [英] Perl6: check if STDIN has data

查看:29
本文介绍了Perl6:检查 STDIN 是否有数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 Perl 6 脚本中,我想对标准输入进行(最好是非阻塞)检查以查看数据是否可用.如果是这样,那么我就想处理它,否则我想做其他事情.

In my Perl 6 script, I want to do a (preferably non-blocking) check of standard input to see if data is available. If this is the case, then I want to process it, otherwise I want to do other stuff.

示例(consumer.p6):

#!/usr/bin/perl6
use v6.b;
use fatal;
sub MAIN() returns UInt:D {
    while !$*IN.eof {
        if some_fancy_check_for_STDIN() { #TODO: this needs to be done.
            for $*IN.lines -> $line {
                say "Process '$line'";
            }
        }
        say "Do something Else.";
    }
    say "I'm done.";
    return 0;
}

作为 STDIN 生成器,我编写了另一个 Perl6 脚本 (producer.p6):

As a STDIN-Generator I wrote another Perl6 script (producer.p6):

#!/usr/bin/perl6
use v6.b;
use fatal;

sub MAIN() returns UInt:D {
    $*OUT.say("aaaa aaa");
    sleep-until now+2;

    $*OUT.say("nbbasdf");
    sleep-until now+2;

    $*OUT.say("xxxxx");
    sleep-until now+2;

    return 0;
}

如果 consumer.p6 按预期工作,它应该产生以下输出,如果通过 ./producer.p6 |./consumer.p6:

If consumer.p6 works as expected, it should produce the following output, if called via ./producer.p6 | ./consumer.p6:

Process 'aaaa aaa'
Do something Else.
Process 'nbbasdf'
Do something Else.
Process 'xxxxx'
Do something Else.
I'm done.

但实际上,它产生以下输出(如果 if 条件被注释掉):

But actually, it produces the following output (if the if condition is commented out):

Process 'aaaa aaa'
Process 'nbbasdf'
Process 'xxxxx'
Do something Else.
I'm done.

推荐答案

您使用的是 Perl 6 的旧版本,因为 v6.b 是该语言正式发布之前的版本.
所以我下面的一些内容可能需要更新的版本才能工作.

You are using an old version of Perl 6, as v6.b is from before the official release of the language.
So some of what I have below may need a newer version to work.

另外,你为什么使用 sleep-until now+2 而不是 sleep 2?

Also why are you using sleep-until now+2 instead of sleep 2?

一种方法是将 .lines 转换为 Channel,那么你就可以使用 .poll.

One way to do this is to turn the .lines into a Channel, then you can use .poll.

#!/usr/bin/env perl6
use v6.c;

sub MAIN () {
    # convert it into a Channel so we can poll it
    my $lines = $*IN.Supply.lines.Channel;

    my $running = True;
    $lines.closed.then: {$running = False}

    while $running {
        with $lines.poll() -> $line {
            say "Process '$line'";
        }
        say "Do something Else.";
        sleep ½;
    }
    say "I'm done.";
}


请注意,上面的代码当前阻塞在 my $lines = ... 行;所以在第一行进来之前它不会开始做某事.要解决这个问题,你可以执行以下操作


Note that the code above blocks at the my $lines = … line currently; so it doesn't start doing something until the first line comes in. To get around that you could do the following

my $lines = supply {
    # unblock the $*IN.Supply.lines call
    whenever start $*IN.Supply {
        whenever .lines { .emit }
    }
}.Channel;

这篇关于Perl6:检查 STDIN 是否有数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆