use 5.012;
use warnings;
use Data::Dump;

#sub ddx {say @_ }


package main;

my %hash;
@hash{"a".."c"} = 40 ..42;              # init
$hash{k1}{k2}= "VAL";
      

{
    
my %proxy_hash;

tie                                     # bind wrapper
  %proxy_hash,
  'Proxy::TieHash',
  \%hash;                               # redundant, why?

ddx $proxy_hash{a};
ddx $proxy_hash{a};
ddx $proxy_hash{b};
ddx $proxy_hash{k1}{k2};

ddx tied %proxy_hash;
ddx \%proxy_hash;
ddx tied %proxy_hash;
ddx \%proxy_hash;
ddx tied %proxy_hash;
ddx tied %proxy_hash;
exit;

# say $proxy_hash{a};
# #$proxy_hash{a}=666;

#ddx @proxy_hash{"a","b"};
ddx \%proxy_hash;
ddx $proxy_hash{k1}{k2};
ddx \%proxy_hash;
ddx $proxy_hash{k1}{k2};
#ddx $proxy_hash{k1}{k2};



exit;
 



say @proxy_hash{"a".."c"};

delete $proxy_hash{b};

say @proxy_hash{"a".."c"};

#undef %proxy_hash;

#delete( tied %proxy_hash
#untie %proxy_hash;                            # unbind wrapper

say @proxy_hash{"a".."c"};
untie %proxy_hash;
warn "end of scope"
}


BEGIN {
    package Proxy::TieHash;
    use Scalar::Util qw/blessed/;
    use Carp;
    use Data::Dump;
    #sub ddx {say @_ }
    sub TIEHASH  {
        #ddx "TIEHASH: ", 
          my ($class, $orig) = @_;

        my $self = bless {orig => $orig}, $class; # BUGGY leaves a trace in the original data

        return $self;
    }


    sub STORE    { $_[0]->{orig}->{$_[1]} = $_[2] }
    sub FETCH    { _proxy( $_[0]->{orig}{$_[1]} ) }
    sub FIRSTKEY { my $a = scalar keys %{$_[0]->{orig}}; each %{$_[0]->{orig}} }
    sub NEXTKEY  { each %{$_[0]->{orig}} }
    sub EXISTS   { exists $_[0]->{orig}->{$_[1]} }
    sub DELETE   { delete $_[0]->{orig}->{$_[1]} }
    sub CLEAR    { %{$_[0]->{orig}} = () }
   sub SCALAR   { scalar %{$_[0]->{orig}} }
    sub UNTIE    {
        my ($obj,$count) = @_;
        carp "untie attempted while $count inner references still exist"              if $count;
    }
    sub DESTROY {carp "DESTROY"}
    sub _proxy {
        #warn
        my $ref = ref $_[0];
        my $refref = ref \$_[0];
        #warn "PROXY <$refref> <$ref>";
        if ( $refref eq "REF" ) {
            if ($ref eq "HASH") {
                tie  my %proxy_hash,  __PACKAGE__,   $_[0]; 
                return \%proxy_hash;
            }
            
        } elsif( $refref  eq "SCALAR" ) {
#            warn "SCALAR <$refref> <$ref>";
            return "<<$_[0]>>";
        } else {
            warn "UNKNOWN TYPE <$refref> <$ref>";
            
        }
        
    }
}






exit;


