有限オートマトンの習作として
PerlでFSM::Simpleというモジュールを書いてみた。
#!perl -w use strict; use warnings; use FSM::Simple; my $count = 0; my $fsm = FSM::Simple->new({ rules => { init => sub { my $state = shift; if ($count < 20) { $state->next('add'); } else { $state->next('end'); } }, add => sub { ++$count; shift->next('init'); } } }); $fsm->register(end => sub { $count *= 5; }); $fsm->run; print "${count}\n"; # => 100
→ Perl Automata
ここを参考にしながら書きました。
ソースはこっちにあります。
→ taiyoh/p5-FSM-Simple · GitHub
(追記:9/3)
同僚からtransaction guardはちゃんと実装した方がいいと言われたので、
インターフェイスを大幅変更。
contextオブジェクトを内部で持つようにして、それで値を取り回すように。
あとはon_entry/on_exit/on_transactionも入れた。
stateのコードとtransaction guardを分けてみたらFSA::Rulesに近くなった。
use FSM::Simple; my $fsm = FSM::Simple->new({ on_enter => sub { my $context = shift; $context->{count} = 0; $context->{str} = "foo"; }, on_transition => sub { shift->{str} .= "bar" }, on_exit => sub { shift->{str} .= "baz" } }); $fsm->register(init => sub {}, [ add => sub { shift->{count} < 20 }, end => sub { shift->{count} >= 20 } ]); $fsm->register(add => sub { ++shift->{count} }, [ init => 1 ]); $fsm->register(end => sub { shift->{count} *= 5 }); $fsm->run; print $fsm->context->{count}, # => 100