Graph::Easy::StateMachine - create a FSA framework from a Graph::Easy graph
Create state machine classes, also known as a FSA or a DFSA, from a state machine description in Graph::Easy's graph description language. States, and their methods, are available in derived classes that use it too.
use Graph::Easy::StateMachine; my $graph = Graph::Easy->new( <<FSA ); [ BASE ] = EnterStateMachine => [ START ] => [ disconnected ] = goodconnect => [ inprogress ] = goodconnect => [ connected ] = sentrequest => [ requestsent ] = readresponse => [ haveresponse ] = done => [ END ] # Try pasting this into the form # at http://bloodgate.com/graph-demo [ disconnected ], [ inprogress ], [connected ] , [ requestsent ] , [ haveresponse ] -- whoops --> [FAIL] -- LeaveStateMachine --> [BASE] FSA eval $graph->as_FSA( base => 'SelectableURLfetcher') or die "FSA parser failure: $@";
Alternately, use the import method to eval the FSA for you.
import
package SelectableURLfetcher; use Graph::Easy::StateMachine <<FSA; [ BASE ] = EnterStateMachine => [ START ] => [ disconnected ] = goodconnect => [ inprogress ] = goodconnect => [ connected ] = sentrequest => [ requestsent ] = readresponse => [ haveresponse ] = done => [ END ] # Try pasting this into the form # at http://bloodgate.com/graph-demo [ disconnected ], [ inprogress ], [connected ] , [ requestsent ] , [ haveresponse ] -- whoops --> [FAIL] -- LeaveStateMachine --> [BASE] FSA
This module adds a new layout engine to Graph::Easy. The as_FSA layout engine produces evaluatable perl code implementing the graph as a set of namespaces each containing methods for all transitions to other states.
Absent a label on an edge from [A] to [B], state A's method to transition to state B is called B.
B
Node names represent states, labeled edges are aliases for the enter methods.
In the example in the previous section, the SelectableURLfetcher::disconnected::goodconnect method reblesses a SelectableURLfetcher::disconnected object into the SelectableURLfetcher::inprogress package, while the SelectableURLfetcher::inprogress::goodconnect method reblesses an inprogress object into the connected state. That is, states are represented by packages, and transitioning occurs by reblessing the object.
SelectableURLfetcher::disconnected::goodconnect
SelectableURLfetcher::disconnected
SelectableURLfetcher::inprogress
SelectableURLfetcher::inprogress::goodconnect
inprogress
connected
Graphs presented to as_FSA must have uniquely named edges.
as_FSA
[A] - next -> [B] [A] - next -> [C]
is a syntax error and will croak.
single inheritance from the base class and transition methods are all that gets defined. You have to set up your own convention for using them. Something like
for (@AsyncObjects) { $_->OnEntry(); $_->${ $_->run ? \'HappyPath' : \'Problem' }() }
As of version 0.06, state namespaces now inherit from the equivalent namespace in all parent classes.
When a base class of other derived classes has state machine classes and methods associated with it via this tool invoked by presenting the graphs on the use line (yes, graphs. Transitions described in later graphs will clobber transitions in earlier graphs.) derived classes may bring in the state machines from their parent classes like so
use
package MyDerivedStatelyClass; use base MyParentStatelyClass; use Graph::Easy::StateMachine;
When the derived class has some variation in its state machine, the variation is all that needs to be enumerated. When a parent class has a state class, such as ExampleParent::UNVERIFIED, and a child class uses this module, the resulting ExampleChild::UNVERIFIED package will list ExampleParent::UNVERIFIED in its @ISA list, so a method such as
@ISA
sub ExampleParent::UNVERIFIED::isVerified{0}
will be available to objects in the ExampleChild::UNVERIFIED state class.
ExampleChild::UNVERIFIED
This works by reevaluating all the graphs from the superclasses with regard to the the current package. No facility is made for state transitions between BASE classes.
as_FSA takes named parameters that control the produced source code.
Altering these is not supported when specifying graphs on the use line.
the base parameter specifies the name space prefix for the state machine class system. When base is not specified, the current package is used.
base
the BASESTATE parameter reserves a state to indicate transitioning to the base package. When not specified, the default is BASE. While invalid transitions will normally throw perl runtime "Can't locate object method" errors, attempts to call invalid transition methods that are valid from the base state throw "invalid transition" errors.
BASESTATE
BASE
before adding the bit to as_FSA that enumerates all the methods that can be used to transition from the base state into the state machine, it would have been necessary to explicitly list all the entry methods to prevent inheritance from allowing them in all states.
package Acme::Bibbity::Bobbity::Boo; use Graph::Easy::StateMachine <<FSA; [BASE] - getwand -> [HAVEWAND] [ PLAINDRELLA ] - domagic -> [FANCYDRELLA] - domagic -> [ATBALL] - midnight -> [REPUMPKINIZING] [BASE] - BeDrella -> [PLAINDRELLA] [PLAINDRELLA],[FANCYDRELLA] - getwand -> [ERROR] ... FSA
in version 0.03, transitions from BASE are noted and all states get their own set of methods that throw errors if they haven't got an entry method. By entry method I mean a method that transitions from BASE into a state class. In the example above, getwand and BeDrella are entry methods.
getwand
BeDrella
writes the as_FSA method into Graph::Easy's name space.
Original version
switched from enter_X to the simpler X for the default transition method name
enter_X
X
added invalid method error-throwers
inheritance
syntax check for ambiguous edges
added inheritance from existing state classes in parents
http://en.wikipedia.org/wiki/Finite_state_automata for theory. Also http://en.wikipedia.org/wiki/Automata-based_programming and http://en.wikipedia.org/wiki/Event-driven_programming
Graph::Easy for how to create your graph
Please use http://rt.cpan.org to report bugs and share patches
This tool is copyright (C) 2009 by David Nicol <davidnico@cpan.org>; The FSA source code generated with it is copyrightable by whoever wrote the graph.
To install Graph::Easy::StateMachine, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Graph::Easy::StateMachine
CPAN shell
perl -MCPAN -e shell install Graph::Easy::StateMachine
For more information on module installation, please visit the detailed CPAN module installation guide.