كيف يمكنني اختبار ستدين دون عرقلة في بيرل?

StackOverflow https://stackoverflow.com/questions/14118

  •  08-06-2019
  •  | 
  •  

سؤال

أنا أكتب أول بيرل التطبيق-وهو AOL Instant Messenger بوت أن المحادثات إلى Arduino, والتي بدورها تتحكم مضاعفات من شأنها أن تضغط على زر الطاقة على مسؤول النظام الملقم الذي يتجمد بشكل عشوائي كل 28 ساعة أو نحو ذلك.

لقد حصلت على جميع الأشياء الصلبة القيام به, أنا فقط أحاول أن أضيف الجزء الأخير من التعليمات البرمجية إلى كسر حلقة الرئيسية و تسجيل الخروج من الهدف عندما يكتب المستخدم 'إنهاء'.

المشكلة إذا حاولت قراءة من STDIN في البرنامج الرئيسي حلقة ، كتل العملية حتى الإدخال إدخال أساسا التقديم بوت غير نشط.لقد حاولت اختبار EOF قبل القراءة ، ولكن لا الزهر...EOF دائما بإرجاع false.

وإليك فيما يلي بعض التعليمات البرمجية أنا أعمل مع:

while(1) {
    $oscar->do_one_loop();

# Poll to see if any arduino data is coming in over serial port
    my $char = $port->lookfor();

# If we get data from arduino, then print it
    if ($char) {
        print "" . $char ;
    }

    # reading STDIN blocks until input is received... AAARG!
    my $a = <STDIN>;
    print $a;
    if($a eq "exit" || $a eq "quit" || $a eq 'c' || $a eq 'q') {last;}
}

print "Signing off... ";

$oscar->signoff();
print "Done\n";
print "Closing serial port... ";
$port->close() || warn "close failed";
print "Done\n";
هل كانت مفيدة؟

المحلول

Perl المدمج في select(), الذي هو تمرير من خلال select() استدعاء النظام ، ولكن العقلاء أوصي IO::Select.

نموذج التعليمات البرمجية:

#!/usr/bin/perl

use IO::Select;

$s = IO::Select->new();
$s->add(\*STDIN);

while (++$i) {
  print "Hiya $i!\n";
  sleep(5);
  if ($s->can_read(.5)) {
    chomp($foo = <STDIN>);
    print "Got '$foo' from STDIN\n";
  }
}

نصائح أخرى

وجدت أن IO::حدد يعمل بشكل جيد طالما المعياري يحصل مغلقة ، مثل عند المنبع عملية في خط أنابيب في المخارج أو الإدخال من ملف.ومع ذلك ، إذا كان الناتج الجارية (مثل من "ذيل -f") ثم أي جزئية من البيانات مخزنة من قبل <STDIN> لن يتم عرض.بدلا من, استخدام unbuffered sysread:

#!/usr/bin/perl
use IO::Select;
$s = IO::Select->new(\*STDIN);

while (++$i) {
        if ($s->can_read(2)) {
                last unless defined($foo=get_unbuf_line());
                print "Got '$foo'\n";
        }
}

sub get_unbuf_line {
        my $line="";
        while (sysread(STDIN, my $nextbyte, 1)) {
                return $line if $nextbyte eq "\n";
                $line .= $nextbyte;
        }
        return(undef);
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top