#!/usr/bin/perl
package Class::Workflow::Transition::Deterministic;
use Moose::Role;
use Carp qw/croak/;
has to_state => (
does => "Class::Workflow::State",
is => "rw",
required => 0,
);
# FIXME augment + inner
requires "apply_body";
sub apply {
my ( $self, $instance, @args ) = @_;
my ( $set_instance_attrs, @rv ) = $self->apply_body( $instance, @args );
$set_instance_attrs ||= {}; # should really die if it's bad
my $new_instance = $self->derive_and_accept_instance(
$instance => {
state => ( $self->to_state || croak "$self has no 'to_state'" ),
%$set_instance_attrs,
},
@args,
);
return wantarray ? ($new_instance, @rv) : $new_instance;
}
__PACKAGE__;
__END__
=pod
=head1 NAME
Class::Workflow::Transition::Deterministic - A transition which knows which
state it leads to.
=head1 SYNOPSIS
package MyTransition;
use Moose;
with qw/
Class::Workflow::Transition
Class::Workflow::Deterministic
/;
sub apply_body { # instead of 'sub apply'
# body
}
# this may be changed to the following form in the future:
augment apply => sub {
# body
};
=head1 DESCRIPTION
This role provides a base role for transitions which know their target state.
It overrides C<apply> with a default implementation that will derive an
instance for you, setting C<state> automatically, appending the return value
from C<apply_body> to that list.
You should consume this role unless you need to determine the target state
dynamically (probably not a good idea).
=head1 FIELDS
=over 4
=item to_state
The target state of the transition. Should do L<Class::Workflow::State>.
=back
=head1 METHODS
=over 4
=item apply
In scalar context returns the derived instance, in list caller also returns the
remaining return value from C<apply_body>.
=back
=head1 REQUIRED METHODS
=over 4
=item apply_body
The "inner" body of the function.
This method is always evaluated in list context, and is expected to return a
hash reference of overridden fields as the first value in that list.
In the future instead of defining C<apply_body> you will do:
augment apply => sub {
# body
};
And this role's C<apply> will really use C<inner()>.
=back
=cut