in reply to Is there a module to save and restore all package variables
It seems to me you're heading down the wrong path. If we knew the big picture better (What are these package vars? Why do they need to restore them?), perhaps you could help you better.
Or maybe it's as simple as moving the variables from the package to a hash or object. Then you could dclone or freeze the hash to make a "backup" of it.
Here's an implementation that uses a hash:
use Scope::Guard qw( ); my %state; { my $backup = freeze(\%state); my $sentinel = Scope::Guard->new(sub { %state = %{ thaw($backup) }; }); $state{a} = ...; push @{$state{b}}, ...; $state{c}{key} = ...; if (success) { $sentinel->dismiss(); } }
The advantage of using Scope::Guard is that the changes to %state will get undone automatically if you return or die before reaching the end of the block.
Update: Here's the class version:
{ package AtomicState; # yucky name! sub new { my ($class) = @_; return bless({}, $class); } sub transaction { my ($self) = @_; return AtomicState::Transaction->new($self); } } { package AtomicState::Transaction; sub new { my ($class) = @_; my $obj_ref = \$_[1]; my $self = bless([ $obj_ref, undef ], $class); $self->commit(); return $self; } sub start_transaction { my ($self) = @_; my $backup = freeze($self); return AtomicState::Transaction->new($self); } # Multiple commits are allowed. sub commit { my ($self) = @_; $self->[1] = freeze(${$self->[0]}); } # Rolls back to the last commit, the first # being the creation of the the Transaction. sub rollback { my ($self) = @_; ${$self->[0]} = thaw($self->[1]); } sub DESTROY { my ($self) = @_; $self->rollback(); } } my $state = AtomicState->new(); { my $transact = $state->transaction(); $state->{a} = ...; push @{$state->{b}}, ...; $state{c}->{key} = ...; if (success) { $transact->commit(); } }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Is there a module to save and restore all package variables
by Anonymous Monk on Aug 06, 2007 at 07:24 UTC |