#!/usr/bin/perl package Class::Workflow::Instance; use Moose::Role; with 'MooseX::Clone'; has prev => ( # the instance this instance was derived from does => "Class::Workflow::Instance", is => "ro", required => 0, ); has transition => ( # the transition this instance is a result of does => "Class::Workflow::Transition", is => "ro", required => 0, ); has state => ( # the state the instance is currently in does => "Class::Workflow::State", is => "ro", required => 1, ); sub derive { my ( $self, @fields ) = @_; $self->clone( @fields, prev => $self ); } sub _clone { my ( $self, @args ) = @_; $self->clone(@args); } # FIXME push this feature to MooseX::Clone by using special values ( \$MooseX::Clone::CLEAR or somesuch ) around clone => sub { my ( $next, $self, %fields ) = @_; my @clear = grep { not defined $fields{$_} } keys %fields; delete @fields{@clear}; my $clone = $self->$next(%fields); my $meta = Class::MOP::get_metaclass_by_name(ref $self); foreach my $field ( @clear ) { $meta->find_attribute_by_name($field)->clear_value($clone); } return $clone; }; __PACKAGE__; __END__ =pod =head1 NAME Class::Workflow::Instance - An instance in a workflow, with state and history. =head1 SYNOPSIS package MyInstance; use Moose; with qw(Class::Workflow::Instance); my $instance = MyInstance->new( state => $initial_state ); my $new_instance = $transition->apply( $instance, @args ); # $instance is in $initial state, no transitions applied # $new_instance may be in another state, $transition has been applied # $new_instance->prev == $instance =head1 DESCRIPTION A workflow instance encapsulates the current state and workflow history on behalf of some parent object that needs state management. In L these instances are functionally pure, that is they don't change but instead derive their parent copies, and the reference from a given item is to the most recently derived copy. This eases auditing, reverting, and the writing of transitions. =head1 FIELDS =over 4 =item state The state this instance is in. Required. =item prev The L object this object was derived from. Optional. =item transition The transition that created this instance from C. =back =head1 METHODS =over 4 =item derive %fields Clones the object, setting C to the current object, and shadowing the fields with new values from the key value pair list in the arguments. =item clone %fields The low level clone operation. If you need to override L based cloning, because your instance objects are e.g. L objects (see the F directory), then you would likely want to override this. See L for more details. =back =cut