NAME
StateMachine::Gestinanna - provides context and state machine for wizard-like applications
SYNOPSIS
package My::Wizard;
@ISA = qw(StateMachine::Gestinanna);
%EDGES => {
# state edge descriptions
start => {
show => {
# conditions for transition
},
.
:
},
.
:
};
# code for state transitions
sub start_to_show {
my $statemachine = shift;
# do something if going from start to show
}
###
package main;
my $sm = new My::Wizard(context => $context);
$sm -> process($data);
my $state = $sm -> state;
DESCRIPTION
StateMachine::Gestinanna is designed to make creation of web-based wizards almost trivial. The module supports inheritance of state information and methods so classes of wizards may be created.
CREATING A STATE MACHINE
The state machine consists of two parts: the conditions for transitioning between states (the edges), and the code that is run when there is a state transition. The meaning of a particular state (e.g., displaying a web page) is left to the application using the state machine. This allows for maximum flexibility in user interfaces.
Edge Descriptions
The package variable %EDGES contains the edge descriptions. The keys of the hash are the states the edges are from and refer to a hash whose keys are the states the edges are to. These keys then point to a hash with a description of the requirements for an edge transition
The requirements should be suitable for giving to Data::FormValidator. See Data::FormValidator for more information.
Code Run During a Transition
Three different methods may be associated with a transition. In this section, replace from and to in the method names with the names of the appropriate states.
If the code needs to preempt the expected target state, it can throw a StateMachine::Gestinanna::Exception with the new target state. The state machine will start over with the new target state.
When no error states are thrown and the transition is successful, the state machine will halt.
- from_to_to
-
This method handles the complete transition and is the only method used if it is available. The name of this method is based on the name of the two states:
${from_state}_to_${to_state}. For example, if we are transitioning from thefoostate to thebarstate, this method would be namedfoo_to_bar. - post_from
-
If the
from_to_tomethod is unavailable, this method is called, if it is available. - pre_to
-
If the
from_to_tomethod is unavailable, this method is called, if it is available.
Throwing Exceptions
The state machine will catch any exceptions of the StateMachine::Gestinanna::Exception class and try to extract a new target state and supplimental data. This exception class inherits from the Error module.
Inheritance
State machines have two forms of inheritance: ISA and HASA.
ISA Inheritance
State machines can inherit all, some, or none of the edges in their inheritance tree. The default is to merge all the edges from all the super-classes. This behavior may be changed by using the _INHERIT key.
%EDGES = (
_INHERIT => 'SUPER',
.
:
);
The following values are recognized.
- ALL
-
This is the default behavior. All edges from all the classes in
@ISAare inherited. If the same edge is in multiple classes, the requirements are merged (may be modified by specifying the _INHERIT flag in the requirements section for a particular edge). - SUPER
-
This is similar to inheritance in Perl. The first class in the
@ISAtree that has a particular edge describes that edge. - NONE
-
This is used to keep any edges from being inherited.
Note that this setting does not affect the inheritance of class methods. The code triggered by a transition follows the inheritance rules of Perl.
HASA Inheritance
A state machine may contain copies of other state machines and put their state names in their own name space. For example, if a module by the name of My::First::Machine has a state of step1 and a second module has the following HASA definition, then step1 becomes the new state of first_step1 in My::Second::Machine.
package My::Second::Machine;
%HASA = (
first => 'My::First::Machine',
);
The methods called on transition may be overridden in the parent machine by defining them with the prefix: My::Second::Machine::first_state1_to_first_state2 overrides My::First::Machine::state1_to_state2. This is done outside Perl's inheritance mechanisms, so calling the method on the state machine object will not show the same behavior.
METHODS
add_data ($root, $data)
This will add the information in $data to the internal data stored in the state machine. The data will be placed under $root. If $root contains periods (.), it will be split on them and serve as a set of keys into a multi-dimensional hash.
clear_data ($root)
This will remove all data under $root that is stored in the state machine.
context ($context)
If called with no arguments, returns a string representing the current context of the state machine. If called with a single argument, restores the state machine to the context represented by $context.
The context is serialized using YAML.
data ($root)
This will retrieve a hash of data stored in the state machine. The $root can be used to retrieve only a sub-set of the data.
Parts of the $root may be separated by periods (.). For example, data("foo.bar") will return $data{foo}{bar}. data("foo") will retrieve anything added with add_data("foo", {}).
The following roots are used by the state machine:
- in
-
This is the data given to the
processmethod. This is used to determine which state the machine should transition to. - out
-
This is the data processed by the Data::FormValidator object for the selected state. Additional processing may take place in the code triggered by the transition.
- error
-
This is any data specified in the error state transition object (the thrown StateMachine::Gestinanna::Exception).
invalid ( )
Returns a reference to a list of keys in the input data that are considered invalid by the validator for the new state.
missing ( )
Returns a reference to a list of keys that are missing in the input data as determined by the validator for the new state.
new (%config)
Constructs a new state machine instance. Any class initialization will take place also the first time the class is used. This involves caching inherited information and creating the validators. Any changes to the %EDGES hash will be ignored after this takes place.
The %config hash may have the following items.
- context
-
This is a string previously returned by the
contextmethod. This can be used to set the machine to a previous state. - state
-
This will set the machine to the given state regardless of the context.
process ($data)
Given a reference to a hash of data, this will select the appropriate state to transition to, and then transition to the new state. This is usually the method you need.
select_state ( )
Given the data and current state in the context, selects the new state. This is used internally by process.
selected_state ( )
Returns the state most recently selected by the select_state method. If no state was selected, it will return undef or the current state, depending on what select_state decides.
state ($state)
If called without an argument, returns the current state. If called with an argument, sets the state to the argument and returns the previous state.
transit ($state)
This will try and transition from the current state to the new state $state. If there are any errors, error states may be processed. This is used internally by process.
unknown ( )
Returns a reference to a list of keys in the input data that are unknown to the validator for the new state.
SEE ALSO
Data::FormValidator, Error, YAML, the test scripts in the distribution.
AUTHOR
James G. Smith <jsmith@cpan.org>
COPYRIGHT
Copyright (C) 2002 Texas A&M University. All Rights Reserved.
This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
4 POD Errors
The following errors were encountered while parsing the POD:
- Around line 655:
=back doesn't take any parameters, but you said =back 4
- Around line 700:
=back doesn't take any parameters, but you said =back 4
- Around line 779:
=back doesn't take any parameters, but you said =back 4
- Around line 813:
=back doesn't take any parameters, but you said =back 4