package My::Guard;
use strict;
sub new {
bless $_[1] => $_[0];
};
sub DESTROY {
$_[0]->()
};
The full (and really pure Perl) program then becomes:
#!perl -w
package My::Guard;
use strict;
sub new {
bless $_[1] => $_[0];
};
sub DESTROY {
$_[0]->()
};
package main;
use strict;
sub alias {\@_};
sub localize {
my @values = @{ +pop }; # or any other convenient method
my $aliases=alias(@_);
my @saved= @_;
#warn Dumper \@saved;
$_[$_] = $values[$_] for 0..$#values;
My::Guard->new(sub{
$aliases->[$_]=$saved[$_] for 0..$#saved;
})
};
my ($a,$b)=('a','b');
print "Start\n";
print qq($a $b),"\n";
my $restore=localize($a,$b,['foo','bar']);
print "Localized\n";
print qq($a $b),"\n";
undef $restore;
print "Restored\n";
print qq($a $b), "\n";
But still, you haven't convinced me that there are problems to which Scope::Upper is a good solution.
Update: As an afterthought, for somebody who thinks they need Scope::Upper, I think you should investigate the easier and potentially less powerful methods first, like having a destructor invoke a callback. I don't consider this a rare/outlandish technique, and there are many packages implementing this, like AtExit, Aspect::Guard, Scope::Guard and ReleaseAction.
Update2: Of course, this clever idea has a big drawback. It doesn't work for arrays and hashes. |