AnyEvent練習帳

まだよく分かっていないAnyEvent。


第13回 AnyEvent:イベント駆動モジュールの方言を吸収する:モダンPerlの世界へようこそ|gihyo.jp … 技術評論社のサンプルコードを参考に、
タイマーと入力読み取りを並行でやるようなものを書いてみた。

#!/opt/local/bin/perl
use strict;
use warnings;

use AnyEvent;
use Term::ReadKey;

my $cv_timer = AnyEvent->condvar;
my $timer; $timer = AnyEvent->timer(
    after    => 0,
    interval => 1,
    cb       => sub {
        print AnyEvent->time, "\n";
        $cv_timer->send;
    },
);
$cv_timer->recv;

ReadMode 4;
while (1) {
    my $cv = AnyEvent->condvar;
    my $io; $io = AnyEvent->io(
        fh   => \*STDIN,
        poll => 'r',
        cb   => sub {
            my $key;
            while (!defined($key = ReadKey(-1))) {
            }
            undef $io;
            $cv->send($key);
        },
       );
    my $input = $cv->recv;
    last if $input eq 'q';
    print "got: [$input]\n";
}

ReadMode 0;
undef $timer;


実行例:

$ readkey.pl
1253983732.64373
1253983733.65415
1253983734.66441
got: [a]
1253983735.67763
got: [b]
1253983736.68528
1253983737.69556
got: [h]
got: [o]
got: [g]
got: [e]
1253983738.70159
1253983739.71184
1253983740.72212

タイマーは1秒毎に時間を表示しつつ、キー入力があればそのたびにそれを表示する。
何故かCtrl+Cが効かなくなるので"q"で停止するようにした。


例えば標準入力から何かを読み込むとかの場合、普通は他の処理をブロッキングしてしまうが、AnyEventを使うことでそれを回避して、「本当に入力があったときだけ処理を行う」といったことができるようになる、ということなのかな。


これを使えば今作っているものができそうな気がする…