Alzabo
view release on metacpan or search on metacpan
lib/Alzabo/ChangeTracker.pm view on Meta::CPAN
package Alzabo::ChangeTracker;
use strict;
use vars qw( $VERSION $STACK @CHANGES );
$VERSION = 2.0;
use Params::Validate qw( :all );
Params::Validate::validation_options( on_fail => sub { Alzabo::Exception::Params->throw( error => join '', @_ ) } );
1;
sub new
{
my $proto = shift;
my $class = ref $proto || $proto;
++$STACK;
my $self = $STACK;
bless \$self, $class;
}
sub add
{
my $self = shift;
validate_pos( @_, { type => CODEREF } );
push @CHANGES, shift;
}
sub backout
{
my $self = shift;
$_->() foreach @CHANGES;
@CHANGES = ();
}
sub DESTROY
{
--$STACK;
@CHANGES = () unless $STACK;
}
__END__
=head1 NAME
Alzabo::ChangeTracker - Saves a set of changes as callbacks that can be backed out if needed
=head1 SYNOPSIS
use Alzabo::ChangeTracker;
my $x = 0;
my $y = 1;
sub foo
{
my $tracker = Alzabo::ChangeTracker->new;
$tracker->add( sub { $x = 0; } );
$x = 1;
bar();
eval { something; };
$tracker->backout if $@;
}
sub bar
{
my $tracker = Alzabo::ChangeTracker->new;
$tracker->add( sub { $y = 1; } );
$y = 2;
}
=head1 DESCRIPTION
The trick ...
We only want to have one object of this type at any one time. In
( run in 0.627 second using v1.01-cache-2.11-cpan-39bf76dae61 )