NAME
Class::StateMachine::Declarative - Define state machines classes in a high level declarative fashion
SYNOPSIS
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
DESCRIPTION
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:
use parent 'My::StateMachine::BaseClass';
use Class::StateMachine::Declarative @decl;
The following attributes can be used to define the state behaviour:
- enter => $method
-
method to be called when the object enters in the state
- leave => $method
-
method to be called when the object leaves the state
- advance => $event
-
when this event (method call) happens the state is changed to the next one declared.
- before => \%before
-
where %before contains pairs
$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
orignore
action is carried out.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 bothbefore
actions will be called when on the substate.For instance:
Class::StateMachine::Declarative foo => { ignore => ['bar'], before => { bar => 'bar_from_foo' }, substates => [ doz => { before => { bar => 'bar_from_doz' } } ] };
Invoking
bar
from the statefoo/doz
calls bothbar_from_foo
andbar_from_doz
methods.Note that
before
actions are not carried out when the principal action is marked as delayed (via thedelay
declaration).Before actions is the ideal place to propagate events to other objects.
- on => \%on
-
where %on contains pairs
$event => $action
When any of the events in the declaration happens the corresponding given action is called.
- transitions => \%transitions
-
where %transitions contains pairs
$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
andenter_state
hooks on the way). - ignore => \@event_list
-
When any of the given events happen, they are ignored.
before
actions defined are executed though. - delay => \@event_list
-
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. - jump => $target_state
-
When the object enters in this state it immediately changes its state to the given one.
- substates => \@substates
-
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.
SEE ALSO
COPYRIGHT AND LICENSE
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.