package Class::Privacy::Proxy; use strict; use Class::Privacy qw/:access_types/; my %hiddens = ( ); # hash keys are Proxy objects sub TIESCALAR { my $class = shift; my $f; $class->_tie(\$f, @_); } sub TIEHASH { my $class = shift; $class->_tie({}, @_); } sub TIEARRAY { my $class = shift; $class->_tie([], @_); } sub _tie { my $class = shift; my ($self, $hidden) = @_; $hiddens{"Class::Privacy::Proxy=$self"} = $hidden; # avoid tieing before we do this CORE::bless($self, $class); return $self; } sub DESTROY { my $self = shift; undef $hiddens{$self}; } # methods for tied variables sub FETCH { my $self = shift; Class::Privacy::_privacy_check($self, $hiddens{$self}, 1, $_[0]); if ($hiddens{$self} =~ /\=ARRAY/) { return $hiddens{$self}->[$_[0]]; } elsif ($hiddens{$self} =~ /\=HASH/) { return $hiddens{$self}->{$_[0]}; } else { return $hiddens{$self}; } } sub STORE { my $self = shift; Class::Privacy::_privacy_check($self, $hiddens{$self}, 2, $_[0]); if ($hiddens{$self} =~ /\=ARRAY/) { $hiddens{$self}->[$_[0]] = $_[1]; } elsif ($hiddens{$self} =~ /\=HASH/) { $hiddens{$self}->{$_[0]} = $_[1]; } else { $hiddens{$self} = shift; } } sub DELETE { my $self = shift; Class::Privacy::_privacy_check($self, $hiddens{$self}, 2, $_[0]); if ($hiddens{$self} =~ /\=ARRAY/) { delete $hiddens{$self}->[$_[0]]; } else { delete $hiddens{$self}->{$_[0]}; } } sub EXISTS { my $self = shift; Class::Privacy::_privacy_check($self, $hiddens{$self}, 1, $_[0]); if ($hiddens{$self} =~ /\=ARRAY/) { return exists $hiddens{$self}->[$_[0]]; } else { return exists $hiddens{$self}->{$_[0]}; } } # hashes only sub FIRSTKEY { my $self = shift; Class::Privacy::_privacy_check($self, $hiddens{$self}, 1, undef); # copied from Tie::Hash. Don't understand reason. my $a = scalar keys %{$hiddens{$self}}; each %{ $hiddens{$self} }; } sub CLEAR { my $self = shift; Class::Privacy::_privacy_check($self, $hiddens{$self}, 2, undef); foreach (keys %{ $hiddens{$self} }) { delete $hiddens{$self}->{$_}; } } sub NEXTKEY { my $self = shift; Class::Privacy::_privacy_check($self, $hiddens{$self}, 1, undef); each %{ $hiddens{$self} }; } # arrays only sub FETCHSIZE { my $self = shift; Class::Privacy::_privacy_check($self, $hiddens{$self}, 1, undef); return $#{ $hiddens{$self} }; } sub STORESIZE { my $self = shift; Class::Privacy::_privacy_check($self, $hiddens{$self}, 2, undef); $#{ $hiddens{$self} } = shift; } sub POP { my $self = shift; Class::Privacy::_privacy_check($self, $hiddens{$self}, 2, undef); pop @{$hiddens{$self} }; } sub PUSH { my $self = shift; Class::Privacy::_privacy_check($self, $hiddens{$self}, 2, undef); push @{$hiddens{$self} }, @_; } sub SHIFT { my $self = shift; Class::Privacy::_privacy_check($self, $hiddens{$self}, 2, undef); shift @{$hiddens{$self} }; } sub UNSHIFT { my $self = shift; Class::Privacy::_privacy_check($self, $hiddens{$self}, 2, undef); unshift @{$hiddens{$self} }, @_; } sub SPLICE { my $self = shift; Class::Privacy::_privacy_check($self, $hiddens{$self}, 2, undef); splice @{$hiddens{$self} }, @_; } 1;