File Coverage

blib/lib/Class/Workflow/State/AutoApply.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             package Class::Workflow::State::AutoApply;
4 1     1   1837 use Moose::Role;
  0            
  0            
5              
6             use Carp qw/croak/;
7             use Scalar::Util qw/refaddr/;
8              
9             has auto_transition => (
10             does => "Class::Workflow::Transition",
11             accessor => "auto_transition",
12             predicate => "has_auto_transition",
13             required => 0,
14             );
15              
16             around transitions => sub {
17             my $next = shift;
18             my ( $self, @transitions ) = @_;
19              
20             my @ret = $self->$next( @transitions );
21              
22             # if the auto transition was not in ->transitions( @set ) then delete it
23             if ( @transitions and my $auto = $self->auto_transition ) {
24             $self->auto_transition(undef) unless grep { $_ == $auto } @transitions;
25             }
26              
27             if ( my $auto = $self->auto_transition ) {
28             return $auto, @ret;
29             } else {
30             return @ret;
31             }
32             };
33              
34             around has_transition => sub {
35             my $next = shift;
36             my ( $self, $transition ) = @_;
37              
38             if ( my $auto = $self->auto_transition ) {
39             if ( ref $transition ) {
40             return 1 if refaddr($auto) == refaddr($transition);
41             } else {
42             return 1 if $auto->can("name") and $auto->name eq $transition;
43             }
44             }
45              
46             return $self->$next($transition);
47             };
48              
49             around accept_instance => sub {
50             my $next = shift;
51             my ( $self, $orig_instance, @args ) = @_;
52             my $instance = $self->$next( $orig_instance, @args );
53              
54             return $self->apply_auto_transition( $instance, @args ) || $instance;
55             };
56              
57             sub apply_auto_transition {
58             my ( $self, $instance, @args ) = @_;
59              
60             if ( my $auto_transition = $self->auto_transition ) {
61             return $auto_transition->apply( $instance, @args );
62             }
63              
64             return;
65             }
66              
67             __PACKAGE__;
68              
69             __END__
70              
71             =pod
72              
73             =head1 NAME
74              
75             Class::Workflow::State::AutoApply - Automatically apply a transition upon
76             arriving into a state.
77              
78             =head1 SYNOPSIS
79              
80             package MyState;
81             use Moose;
82              
83             with qw/Class::Workflow::State::AutoApply/;
84            
85             my $state = Mystate->new( auto_transition => $t );
86              
87             my $i2 = $state->accept_instance( $i, @args ); # automatically calls $t->apply( $i, @args )
88              
89             =head1 DESCRIPTION
90              
91             This state role is used to automatically apply a transition
92              
93             =head1 PARTIAL TRANSITIONS
94              
95             If an auto-application may fail validation or something of the sort you can do
96             something like:
97              
98             around apply_auto_transition => sub {
99             my $next = shift;
100             my ( $self, $instance, @args ) = @_;
101              
102             eval { $self->$next( $instance, @args ) }
103              
104             die $@ unless $@->isa("SoftError");
105             }
106              
107             If apply_auto_transition returns a false value then the original instance will
108             be returned automatically, at which point the intermediate state is the current
109             state.
110              
111             =cut
112              
113