Perl6:检查STDIN是否有数据

前端之家收集整理的这篇文章主要介绍了Perl6:检查STDIN是否有数据前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在我的Perl 6脚本中,我想对标准输入进行(最好是非阻塞)检查以查看数据是否可用.如果是这种情况,那么我想处理它,否则我想做其他的事情.

示例(consumer.p6):

  1. #!/usr/bin/perl6
  2. use v6.b;
  3. use fatal;
  4. sub MAIN() returns UInt:D {
  5. while !$*IN.eof {
  6. if some_fancy_check_for_STDIN() { #TODO: this needs to be done.
  7. for $*IN.lines -> $line {
  8. say "Process '$line'";
  9. }
  10. }
  11. say "Do something Else.";
  12. }
  13. say "I'm done.";
  14. return 0;
  15. }

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

  1. #!/usr/bin/perl6
  2. use v6.b;
  3. use fatal;
  4.  
  5. sub MAIN() returns UInt:D {
  6. $*OUT.say("aaaa aaa");
  7. sleep-until now+2;
  8.  
  9. $*OUT.say("nbbasdf");
  10. sleep-until now+2;
  11.  
  12. $*OUT.say("xxxxx");
  13. sleep-until now+2;
  14.  
  15. return 0;
  16. }

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

  1. Process 'aaaa aaa'
  2. Do something Else.
  3. Process 'nbbasdf'
  4. Do something Else.
  5. Process 'xxxxx'
  6. Do something Else.
  7. I'm done.

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

  1. Process 'aaaa aaa'
  2. Process 'nbbasdf'
  3. Process 'xxxxx'
  4. Do something Else.
  5. I'm done.

解决方法

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

另外你为什么要睡觉 – 直到现在2而不是睡2?

一种方法是将.lines转换为Channel,然后你可以使用.poll.

  1. #!/usr/bin/env perl6
  2. use v6.c;
  3.  
  4. sub MAIN () {
  5. # convert it into a Channel so we can poll it
  6. my $lines = $*IN.Supply.lines.Channel;
  7.  
  8. my $running = True;
  9. $lines.closed.then: {$running = False}
  10.  
  11. while $running {
  12. with $lines.poll() -> $line {
  13. say "Process '$line'";
  14. }
  15. say "Do something Else.";
  16. sleep ½;
  17. }
  18. say "I'm done.";
  19. }

请注意,上面的代码目前在my $lines = …行阻止;因此,在第一行进入之前它不会开始做某事.为了解决这个问题,你可以做到以下几点

  1. my $lines = supply {
  2. # unblock the $*IN.Supply.lines call
  3. whenever start $*IN.Supply {
  4. whenever .lines { .emit }
  5. }
  6. }.Channel;

猜你在找的Perl相关文章