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 simpler X 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.