Class-StateMachine

 view release on metacpan or  search on metacpan

lib/Class/StateMachine.pm  view on Meta::CPAN

  sub foo : OnState(map "foo$_", a..z) { ... }

Though note that lexicals variables will not be reachable from the
text inside the parents. Note also that Perl does not allow attribute
declarations to spawn over several lines.

A special state C<__any__> can be used to indicate a default submethod
that is called in case a specific submethod has not been declared for
the current object state.

For instance:

  sub happy :OnState(happy  ) { say "I am happy" }
  sub happy :OnState(__any__) { say "I am not happy" }

=head2 Method resolution order

What happens when you declare submethods spread among a class
inheritance hierarchy?

Class::StateMachine will search for the method as follows:

=over 4

=item 1

Search in the inheritance tree for a specific submethod declared for
the current object state.

=item 2

Search in the inheritance tree for a submethod declared for the pseudo
state C<__any__>.

=item 3

Search for a regular method defined without the C<OnState> attribute.

=item 4

Use the AUTOLOAD mechanism.

=back

L<mro> can be used to set the search order inside the inheritance
trees (for instance, the default deep-first or C3).

=head2 State transitions

When an object changes between two different states, the methods
L</leave_state> and L</enter_state> are called if they are defined.

Note that they can be defined using the C<OnState> attribute:

  package Dog;
  ...
  sub enter_state :OnState(angry) { shift->bark }
  sub enter_state :OnState(tired) { shift->lie_down }

The method C<on_leave_state> can also be used to register per-object
callbacks that are run just before changing the object state.

=head2 API

These are the methods available from Class::StateMachine:

=over 4

=item Class::StateMachine::bless($obj, $class, $state)

=item $obj-E<gt>bless($class)

Sets or changes the object class in a manner compatible with
Class::StateMachine.

This function must be used as the way to create new objects of classes
derived from Class::StateMachine.

If the third argument C<$state> is not given, C<new> is used as the
default.

=item $obj-E<gt>state

X<state>Gets the object state.

=item $obj-E<gt>state($new_state)

Changes the object state.

This method calls back the methods C<check_state>, C<leave_state> and
C<enter_state> if they are defined in the class or any of its
subclasses for the corresponding state and any callback registered
using the C<on_leave_state> method.

Until version 0.21, when C<$new_state> was equal to the current object
state, this method would not invoke callback methods (C<enter_state>,
C<leave_state>, etc.). On version 0.22 this special casing was
removed.

Setting the variable
C<$Class::StateMachine::ignore_same_state_changes> to a true value
restores the old behavior.

=over 4

=item $self->check_state($new_state)

X<check_state>This callback can be used to limit the set of states
acceptable for the object. If the method returns a false value the
C<state> call will die.

If this method is not defined any state will be valid.

=item $self->leave_state($old_state, $new_state)

X<leave_state>This method is called just before changing the state.

It the state is changed from its inside to something different than
$old_state, the requested state change is canceled.

=item $self->enter_state($new_state, $old_state)

X<enter_state>This method is called just after changing the state to
the new value.

=item $self->on_leave_state($callback, @args)

The given callback is called when the state changes.

C<$callback> may be a reference to a subroutine or a method name. It
is called respectively as follows:

  $callback->(@args);      # $callback is a CODE reference
  $self->$callback(@args); # $callback is a method name

If the calling the C<leave_state> method is also defined, it is called first.

The method may be called repeatedly from the same state and the
callbacks will be executed in FIFO order.

=item $self->delay_until_next_state

=item $self->delay_until_next_state($method_name)

=item $self->delay_until_next_state($code_ref)

This function allows to save a code reference or a method name that
will be called after the next state transition from the C<state>
method just after C<enter_state>.

It is useful when your object receives some message that does not
known how to handle in its current state. For instance:

  sub on_foo :OnState('bar') { shift->delay_until_next_state }

=item $self->delay_once_until_next_state

=item $self->delay_once_until_next_state($method_name)

This method is similar to C<delay_until_next_state> but further
requests to delay the same method will be discarded until the object
state changes. For instance:

  sub foo OnState(one) { shift->delay_once_until_next_state }
  sub foo OnState(two) { print "hello world\n" }

  my $obj = $class->new();
  $obj->state('one');
  $obj->foo; # recorded
  $obj->foo; # ignored!

  $obj->state('two'); # foo is called once here.

Note that this method does not accept a code reference as argument.

=back

=item Class::StateMachine::ref($obj)

=item $obj-E<gt>ref

Returns the class of the object without the parts related to
Class::StateMachine magic.

=item Class::StateMachine::install_method($class, $method_name, $sub, @states)

Sets a submethod for a given class/state combination.

=item Class::StateMachine::set_state_isa($class, $state, @isa)

Allows to set one state as derived from others.

Note that support for state derivation is completely experimental and
may change at any time!

=item Class::StateMachine::state_isa($class, $state)

Returns the list of states from which the given C<$state> derives
including itself and C<__any__>.



( run in 1.664 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )