GUIのイベントを拾ったり、IRCクライアントのように登録したコールバックが何度も呼ばれるパターンでは、return型の関数にするのは難しいと思います。
while でループさせるような作りにしたらできそうですけど、それがわかりやすいかどうか。
やっつけ仕事で一応やってみましたが・・・。特にIRC::Clientで、while内でイベントの種類で分岐しまくる作りとなる辺り、なんか逆行してる感がw
Twitter::Streamの方はいい感じだと思います*1。発生するイベントが1個だと、コールバックが何度も呼ばれるライブラリでもうまくCoroにあいますね。
package main; use strict; use warnings; use Coro; use Encode; use utf8; my $channel = $ARGV[0]; my $c = MyCoro::IRC::Client->new; $c->reg_watcher('connect'); $c->reg_watcher('registered'); $c->reg_watcher('publicmsg'); $c->ae_irc->connect( "irc.nara.wide.ad.jp", 6663, { nick => 'hiratara_bot' } ); $c->ae_irc->send_srv( "JOIN", $channel ); async{ while(my $ev = $c->next){ if( $ev->{event} eq 'publicmsg'){ $c->ae_irc->send_chan( $channel, "NOTICE", $channel, $ev->{args}[2]{params}[1] ); }else{ warn $ev->{event}; }; } }; my $twitter = MyCoro::Twitter::Stream->new( username => $ARGV[1], password => $ARGV[2], method => 'filter', track => '#food', ); async{ while(my $tweet = $twitter->next){ $c->ae_irc->send_chan( $channel, "NOTICE", $channel, encode_utf8( "$tweet->{user}{screen_name}: $tweet->{text}" ) ); } }; schedule;
ライブラリ側も含めた全体は、こちらのgistで。
*1:ただ、エラー処理これじゃ駄目(dieじゃ落ちない)んで調べなきゃ><