MooseX::Graph::Easy::StateMachine - declare state subclasses using Graph::Easy syntax and Any::Moose
Welcome to a world where a Finite State Machine drawing can go right into your source code.
package liquor::consumer; # "I'm not an alchoholic: alchoholics go to meetings." use Any::Moose; use MooseX::Graph::Easy::StateMachine <<GRAPH; [BASE] - WakeUp -> [sober] - drink -> [drunk] - wait -> [sober] [BASE] - drink -> [drunk] [drunk] - passout -> [asleep] - wait -> [BASE] - wait -> [BASE] GRAPH sub live{ my $self = shift; $self->WakeUp } sub liquor::consumer::sober::live { my $self = shift; $self->drink } package alchoholic; use Any::Moose; BEGIN { # this needs to be in a BEGIN block # so the state machine class generator # will be able to see the @ISA extends ('liquor::consumer'); }; has days_sober => (isa => 'Int', is => 'rw', required => 1); use MooseX::Graph::Easy::StateMachine <<GRAPH; [sober] - GoToMeeting -> [sober] [drunk] - GoToMeeting -> [sober] [BASE] - GoToMeeting -> [sober] GRAPH after 'drink' => sub { my $self = shift; $self->days_sober(0); }; after 'GoToMeeting' => sub { my $self = shift; $self->days_sober(1+$self->days_sober); }; sub live{ my $self = shift; $self->GoToMeeting } package alchoholic::sober; use Any::Moose; after ('drink' => sub { my $self = shift; $self->days_sober(0); # the extension is automatic }); after 'GoToMeeting' => sub { my $self = shift; $self->days_sober(1+$self->days_sober); }; package Maine; my $Basil = alchoholic->new(3653); # Basil has been sober for ten years
This module is intended to work exactly like Graph::Easy::StateMachine only using Any::Moose OO instead,
Instead of running string-eval on the output of a layout engine, this module uses <caller()-meta->create>> and closures to generate the state transition methods.
<caller()-
this module does not facilitate creating a role/trait that limits the available values that may be set into a state attribute based on inspecting what the state attribute is currently set to. Doing it that way would make sense from a flexibility and reuse standpoint, at the cost of requiring double method dispatch and a lot of dynamic checking.
Moose's "after" mechanism can't find methods declared like
*{"alchoholic::sober::drink"} = sub{...}
but can find them when declared usint string eval. Mouse's can find both. Also, "after" does not affect equivalent methods in subclasses.
Copyright (C) 2011 David Nicol, <davidnico@cpan.org>
This module is free software; you can redistribute it and/or modify it under the terms of the Creative Commons Attribution 3.0 license http://creativecommons.org/licenses/by/3.0/
Not deleting this section from your installation is sufficient attribution.
To install MooseX::Graph::Easy::StateMachine, copy and paste the appropriate command in to your terminal.
cpanm
cpanm MooseX::Graph::Easy::StateMachine
CPAN shell
perl -MCPAN -e shell install MooseX::Graph::Easy::StateMachine
For more information on module installation, please visit the detailed CPAN module installation guide.