あだ名の多さは人気の証明?
POEという名前にはあきれるほど多くの寓意がこじつけられています。もともとはPerl Object Environment
20世紀最後の大規模プロジェクト
POEが生まれたのは1998年8月のこと。翌1999年の8月には第3回のPerlカンファレンス
20世紀生まれのPOEが
その一方で,
簡単なスクリプトをPOEで書き直してみよう
伝統的なPerlスクリプトは,
use strict;
use warnings;
package MyObj;
sub new {
my ($class, @files) = @_;
bless { files => \@files }, $class;
}
sub do_tasks {
my $self = shift;
while ( my $file = shift @{$self->{files}} ) {
print "processing $file\n";
# 実際にはファイルの解析や圧縮,ダウンロードなどの
# もっと具体的な処理が入るところです
my $counter = int(rand(1_000_000));
1 while $counter--;
}
}
package main;
my $obj = MyObj->new(1..100);
$obj->do_tasks;
POEの場合も,
package main;
use POE;
POE::Session->create(
heap => { obj => MyObj->new(1..100) },
inline_states => {
_start => sub { $_[KERNEL]->yield('do_tasks') },
do_tasks => sub { $_[HEAP]{obj}->do_tasks },
},
);
POE::Kernel->run;
いささか見慣れない表現もありますが,
セッションが始まるとまず_startに登録されている処理が実行されます
シングルタスクからマルチタスクへ
まずはセッションを登録する部分をこのように変えてみます。
POE::Session->create(
heap => { obj => MyObj->new(1..100) },
inline_states => {
_start => sub {
$_[KERNEL]->yield('do_tasks');
$_[KERNEL]->yield('tick');
},
do_tasks => sub { $_[HEAP]{obj}->do_tasks },
tick => sub {
print "tick\n";
$_[KERNEL]->delay(tick => 1);
},
},
);
ところが,
use strict;
use warnings;
package MyObj;
sub new {
my ($class, @files) = @_;
bless { files => \@files }, $class;
}
sub do_task {
my $self = shift;
my $file = shift @{$self->{files}} or return;
print "processing $file\n";
my $counter = int(rand(1_000_000));
1 while $counter--;
return 1;
}
package main;
use POE;
POE::Session->create(
heap => { obj => MyObj->new(1..100) },
inline_states => {
_start => sub {
$_[KERNEL]->yield('do_task');
$_[KERNEL]->yield('tick');
},
do_task => sub {
$_[HEAP]{obj}->do_task and $_[KERNEL]->yield('do_task');
},
tick => sub {
print "tick\n";
$_[KERNEL]->delay(tick => 1);
},
},
);
POE::Kernel->run;
これでずいぶんマシになりました。do_
POE::Session->create(
heap => { obj => MyObj->new(1..100) },
inline_states => {
_start => sub {
$_[KERNEL]->yield('do_task');
$_[KERNEL]->yield('tick');
},
do_task => sub {
$_[HEAP]{obj}->do_task and $_[KERNEL]->yield('do_task');
},
tick => sub {
return unless @{$_[HEAP]{obj}{files}};
print "tick\n";
$_[KERNEL]->delay(tick => 1);
},
},
);
もちろんdo_ POEの公式サイトにも該当の記事がありますのであわせてご覧ください。