Class::StateMachine::Declarative - Define state machines classes in a high level declarative fashion
package Dog; use parent 'Class::StateMachine'; use Class::StateMachine::Declarative __any__ => { ignore => [qw(on_sleep on_feed)], before => { on_knocked_down => 'cry', kicked => 'bark' }, transitions => { on_knocked_down => 'unhappy/injuried', kicked => 'unhappy/angry' } }, happy => { enter => 'move_tail', on => { on_head_touched => 'move_tail' }, transitions => { on_knocked_down => 'injuried', unhappy => { substates => [ injuried => { enter => 'bark', on => { on_head_touched => 'bark' }, transitions => { on_sleep => 'happy' } }, angry => { enter => 'bark', ignore => [qw(kicked)], on => { on_head_touched => 'bite' }, transitions => { on_feed => 'happy' } } ] }; sub new { my $class = shift; my $self = {}; # starting state is set here: Class::StateMachine::bless $self, $class, 'happy'; $self; } package main; my $dog = Dog->new; $dog->on_head_touched; # the dog moves his tail $dog->on_kicked; $dog->on_head_touched; # the dog bites (you!) $dog->on_injuried; $dog->on_head_touched; # the dog barks $dog->on_sleep; $dog->on_head_touched; # the dog moves his tail
Class::StateMachine::Declarative is a Class::StateMachine (from now on C::SM) extension that allows to define most of a state machine class declaratively.
The way to create a new Class::StateMachine derived class from this module is to pass a set of state declarations through its use statement:
use Class::StateMachine::Declarative $state1 => $decl1, $state2 => $decl2, ...;
Note that Class::StateMachine::Declarative will not set @ISA for you, as you may want to derive your classes not from C::SM directly but from some of its subclasses. For instance:
@ISA
use parent 'My::StateMachine::BaseClass'; use Class::StateMachine::Declarative @decl;
The following attributes can be used to define the state behaviour:
method to be called when the object enters in the state
method to be called when the object leaves the state
when this event (method call) happens the state is changed to the next one declared.
where %before contains pairs $event => $action
$event => $action
When any of the events on the declaration happens, the corresponding action (a method actually) will be called before the final advance, on, transition or ignore action is carried out.
advance
on
transition
ignore
Also, before actions are stacked on the hierarchy. So, if you define a before action for a state and then another for some substate, then both before actions will be called when on the substate.
before
For instance:
Class::StateMachine::Declarative foo => { ignore => ['bar'], before => { bar => 'bar_from_foo' }, substates => [ doz => { before => { bar => 'bar_from_doz' } } ] };
Invoking bar from the state foo/doz calls both bar_from_foo and bar_from_doz methods.
bar
foo/doz
bar_from_foo
bar_from_doz
Note that before actions are not carried out when the principal action is marked as delayed (via the delay declaration).
delay
Before actions is the ideal place to propagate events to other objects.
where %on contains pairs $event => $action
When any of the events in the declaration happens the corresponding given action is called.
where %transitions contains pairs $event => $target_state
$event => $target_state
When any of the given events happens, the object state is changed to the corresponding target state (and executing before, leave_state and enter_state hooks on the way).
leave_state
enter_state
When any of the given events happen, they are ignored.
before actions defined are executed though.
When any of the given events happen, no action is executed but they are remembered until the next state change and them called again.
before actions are not called. They will be called when the event is called again from the next state, but them the actual action executed will be that for that state if any.
When the object enters in this state it immediately changes its state to the given one.
An state can have substates.
Most actions are inherited from the state into the substates. For instance, a transition defined in some state will also happen in its substates unless it is overridden by another declaration.
The state __any__ is an special state that is considered the parent of all the other states.
__any__
Class::StateMachine.
Copyright (C) 2011-2014 by Salvador Fandiño <sfandino@yahoo.com>
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.12.4 or, at your option, any later version of Perl 5 you may have available.
To install Class::StateMachine::Declarative, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Class::StateMachine::Declarative
CPAN shell
perl -MCPAN -e shell install Class::StateMachine::Declarative
For more information on module installation, please visit the detailed CPAN module installation guide.