NAME
Graph::Easy::StateMachine - create a FSA framework from a Graph::Easy graph
SYNOPSIS
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.
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
DESCRIPTION
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
.
NODE NAMES
Node names represent states, labeled edges are aliases for the enter methods.
EDGE LABELS
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.
SYNTAX CHECKING
Graphs presented to as_FSA
must have uniquely named edges.
[A] - next -> [B]
[A] - next -> [C]
is a syntax error and will croak.
ALL THIS MODULE DOES
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.
INHERITING FROM A STATELY CLASS
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
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
sub ExampleParent::UNVERIFIED::isVerified{0}
will be available to objects in the ExampleChild::UNVERIFIED
state class.
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.
PARAMETERS TO THE as_FSA METHOD
as_FSA
takes named parameters that control the produced source code.
Altering these is not supported when specifying graphs on the use
line.
base
the base
parameter specifies the name space prefix for the state machine class system. When base
is not specified, the current package is used.
BASESTATE
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.
Mickey Mouse
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.
EXPORT
writes the as_FSA
method into Graph::Easy's name space.
HISTORY
- 0.01
-
Original version
- 0.02
-
switched from
enter_X
to the simplerX
for the default transition method name - 0.03
-
added invalid method error-throwers
- 0.4
-
inheritance
- 0.5
-
syntax check for ambiguous edges
- 0.6
-
added inheritance from existing state classes in parents
SEE ALSO
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
FEEDBACK AND SUPPORT
Please use http://rt.cpan.org to report bugs and share patches
COPYRIGHT AND LICENSE
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.