Class::Workflow::Util::Delta - calculate deltas between workflow instances


Class-Workflow documentation Contained in the Class-Workflow distribution.

Index


Code Index:

NAME

Top

Class::Workflow::Util::Delta - calculate deltas between workflow instances

SYNOPSIS

Top

	my $next = $transition->apply( $i );

	my $d = Class::Workflow::Util::Delta->new(
		from => $i,
		to   => $next,
	);

	foreach my $field ( keys %{ $d->changes } ) {
		my $change = $d->changes->{$field};
		print "$field changed from $change->{from} to $change->{to}\n";
	}

DESCRIPTION

Top

Usually you need to calculate deltas between workflow instances in order to normalize the database of history changes so that there are no duplicate fields.

This module lets you create an object that represents the change between any two instances (not necessarily related), allowing you to represent a history step.

See Class::Workflow::YAML


Class-Workflow documentation Contained in the Class-Workflow distribution.

#!/usr/bin/perl

package Class::Workflow::Util::Delta;
use Moose;

use Carp qw/croak/;

use Data::Compare ();

has from => (
	does => "Class::Workflow::Instance",
	is   => "ro",
	required => 1,
);

has to => (
	does => "Class::Workflow::Instance",
	is   => "ro",
	required => 1,
);

has changes => (
	isa => "HashRef",
	is  => "ro",
	auto_deref => 1,
	lazy => 1,
	default => sub { $_[0]->_compute_changes },
);

sub BUILD {
	my $self = shift;

	croak "The instances must be of the same class"
		unless $self->from->meta->name eq $self->to->meta->name;
}

sub _compute_changes {
	my $self = shift;

	my %changes;

	my ( $from, $to ) = ( $self->from, $self->to );

	my @attrs = $from->meta->get_all_attributes;

	foreach my $attr ( grep { $_->name !~ /^(?:prev|state|transition)$/ } @attrs ) {
		my $res = $self->_compare_values(
			$attr,
			$attr->get_value( $from ),
			$attr->get_value( $to ),
		);

		$changes{$attr->name} = $res if $res;
	}

	return \%changes;
}

sub _compare_values {
	my ( $self, $attr, $from, $to ) = @_;

	unless ( Data::Compare::Compare( $from, $to ) ) {
		return { from => $from, to => $to };
	} else {
		return;
	}
}

__PACKAGE__;

__END__