Acme-FSM

 view release on metacpan or  search on metacpan

lib/FSM.pm  view on Meta::CPAN

    $self->state( $turn->[0] );
    $self->action( $turn->[1] );

    my( $item, $dump ) = $self->query_source;
    $self->diag( 3, q|{%s}(%s): %s: going with|, @$turn, $dump );

# No one gets out of this loop without the state tables permission!
    while ( 1 )                                                     {
# We should never see an undefined state unless we've made a mistake.
# NOTE:202201072131:whynot: As a matter of fact, we don't now.
        $self->verify( $self->fst( $self->state ),
          $self->state, '', q|record|, q|HASH| );

        ( $branch, $item ) = $self->query_switch( $item );
        $self->diag( 5, q|{%s}(%s): switch returned: (%s)|, @$turn, $branch );
        $dump = $self->query_dumper( $item );
        $turn = $self->turn( $self->state, $branch );
        $self->diag( 3, q|{%s}(%s): %s: turning with|,
          $turn->[0], $branch, $dump );
        $self->state( $turn->[0] );
        $self->action( $turn->[1] );

        $self->diag( 5, q|{%s}(%s): going for|, @$turn );
        $turn->[0] eq q|STOP|                                        and last; 
        $turn->[0] eq q|BREAK|                                       and last;
        $turn->[1] eq q|SAME|                                        and redo;
        $turn->[1] eq q|NEXT|                                        and next;
        $turn->[1] eq q|TSTL| && defined $item                       and redo;
        $turn->[1] eq q|TSTL|                                        and next;
        croak sprintf q|[process]: {%s}(%s): unknown action|, @$turn }
    continue                                                        {
        ( $item, $dump ) = $self->query_source;
        $self->diag( 5, q|{%s}(%s): %s: going with|, @$turn, $dump ) }

    $self->diag( 3, q|{%s}(%s): leaving|, @$turn );
# XXX:20121231215139:whynot: Nothing to B<verify()>, leaving anyway.
    $branch = $self->query_switch;
    $self->diag( 5, q|{%s}(%s): switch returned: (%s)|, @$turn, $branch );
    $self->diag( 3, q|{%s}(%s): changing state: (CONTINUE)|, @$turn )
    ->state( q|CONTINUE| )                          if $turn->[0] eq q|BREAK|;
    return $self->action }


=head1 METHODS AND STUFF

Access and utility methods to deal with various moves while doing The State
Flow.
These aren't forbidden for use from outside,
while being quite internal nevertheles.

=over

=cut

=item B<verify()>

    $rc = $self->query_rc( @args );
    $rc = $self->verify( $rc, $state, $tag, $subject, $test );

Here comes rationale.
Writing (or should I say "composing"?) correct {fst} B<A::F> style is hard
(I know what I'm talking about, I've made a dozen already).
The purpose of B<verify()> is to check if the I<{fst}> at hands isn't fubar.
Nothing more, nothing less.
B<query_rc()> is a placeholder for one of B<query_.*()> methods,
I<$test> will be matched against C<ref $rc>.
Other arguments are to fill diagnostic output (if any).
I<$state> hints from what I<{state}> I<$rc> has been queried.
I<$subject> and I<$tag> are short descriptive name and actual value of I<$rc>.
Yup, dealing with B<verify()> might be fubar too.

I<$rc> is passed through (or not).
This B<croak>s if I<$rc> isn't B<defined> or C<ref $rc> doesn't match
I<$test>.

=cut

# TODO:202202150137:whynot: Replace C<return udnef> with B<croak()>, plz.
sub verify       {
    my $self = shift @_;
# XXX:202202092101:whynot: Nope, needs I<$state> because sometimes I<{state}> isn't entered yet.
    my( $entry, $state, $what, $manifest, $test ) = @_;
    defined $entry    or croak sprintf q|[verify]: {%s}(%s): %s !isa defined|,
      $state, $what, $manifest;
    ref $entry eq $test                                       or croak sprintf
      q|[verify]: {%s}(%s): %s isa (%s), should be (%s)|,
      $state, $what, $manifest, ref $entry, $test;
    return $entry }

=item B<state()>

    $bb->state eq 'something' and die;
    $state = $bb->state( $new_state );

Queries and sets state of B<A::F> instance.
Modes:

=over

=item no argument

Returns state of instance.
Note, Perl FALSE B<isa> parameter.

=item lone scalar

Sets I<$state> of instance.
Returns previous I<$state>.

=back

=cut

sub state                        {
    my $self = shift @_;
    unless( @_ )                {
        return $self->{_}{state} }
    elsif( 1 == @_ )            {
        my $backup = $self->state;
        $self->diag( 5, q|changing state: (%s) (%s)|, $backup, $_[0] );
        $self->{_}{state} = shift @_;



( run in 1.343 second using v1.01-cache-2.11-cpan-e1769b4cff6 )