use strict; use warnings; package MyLocal; use PadWalker qw(peek_my); my %old_value; sub new { my $self = shift; my %arg = @_; my $h = peek_my($arg{level}); $arg{h} = $h; bless \%arg; } sub set { my ($self, $variable , $value) = @_; if(! exists $old_value{$variable}) { $old_value{$variable} = ${ $self->{h}{$variable} }; } ${ $self->{h}{$variable} } = $value; } DESTROY { my $self = shift; foreach my $var (keys %old_value) { ${ $self->{h}{$var} } = delete $old_value{$var}; } } package main; my $x = 1; my $f = sub { $x }; { my $loc = MyLocal->new(level => 1); $loc->set('$x' => 2); print $f->(), "\n"; # => 2 } print $f->(), "\n"; # => 1