With Guard, you get to set up a call back when the scope is left to clean up whatever.
For my purposes, the only work to be done at scope exit, is for the previous value of the localized variable to be restored.
All the work is in deriving the value(s) of the variable(s) that need localizing. A common pattern of boilerplate code needed at the *top* of many different scopes and so a candidate for wrapping up in a sub.
But with local you cannot localize variables in your caller. With localize() you can. And the only required clean up is taken care of by the normal scope clean up.
| [reply] [Watch: Dir/Any] |
With Guard, you get to set up a call back when the scope is left to clean up whatever.
Ah - sorry - I meant that the localizing code returns such a guard object, so that the caller can then decide whether to clean up at exit or to pass that guard on upwards again.
I'm still unaware of where that implicit localization-at-a-distance would be good design. The following code seems to me to solve the problem in a pure-perl fashion, and keeps the localization somewhat explicit, instead of prodding through the enclosing pads by name:
#!perl -w
use strict;
use Guard;
sub alias {\@_};
sub localize {
my @values = @{ +pop }; # or any other convenient method
my $aliases=alias(@_);
my @saved= @_;
#warn Dumper \@saved;
$_[$_] = $values[$_] for 0..$#values;
guard {
$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";
__END__
Start
a b
Localized
foo bar
Restored
a b
| [reply] [Watch: Dir/Any] [d/l] |
| [reply] [Watch: Dir/Any] |