LanX has asked for the wisdom of the Perl Monks concerning the following question:
In the following example I'm simply returning any value enclosed in < > .
I'm facing some "complications", which make me doubt I'm doing the right thing.
Any more elegant approach???
use v5.12; use warnings; package main; my %hash; @hash{"a".."c"} = 40 ..42; # init tie # bind wrapper %hash, 'Data::Proxy::TieHash', \%hash; # redundant, why? say $hash{a}; say @hash{"a".."c"}; delete $hash{b}; say @hash{"a".."c"}; untie %hash; # unbind wrapper say @hash{"a".."c"}; BEGIN { package Data::Proxy::TieHash; require Tie::Hash; use Scalar::Util qw/blessed/; use Carp; our @ISA = qw(Tie::ExtraHash); # All methods provided by default, define # only those needing overrides # Accessors access the storage in %{$_[0][0]}; # TIEHASH should return an array reference with the first element # being the reference to the actual storage sub _report { # uncomment to trace #carp "Doing \U$_[0]\E of $_[1] at $_[2].\n" }; sub DELETE { my ($obj, $key) = @_; my ($meta, $orig) =@$obj; _report('DELETE', $orig, $key); my $class = blessed $obj; undef $obj; untie %{$orig}; my $ret = delete $orig->{$key}; tie %{$orig}, $class, $orig; return $ret; } sub FETCH { goto &FETCH1; # use implementation } sub FETCH0 { _report('FETCH', $_[0][1], $_[1]); untie %{$_[0][1]}; my $ret = $_[0][1]->{$_[1]}; tie %{$_[0][1]}, 'Data::Proxy::TieHash', $_[0][1]; return "<$ret>" if defined $ret; return undef; } sub FETCH1 { my ($obj, $key) = @_; my ($meta, $orig) =@$obj; _report('FETCH', $orig, $key); my $class = blessed $obj; undef $obj; # avoid warning untie %{$orig}; my $ret = $orig->{$key}; tie %{$orig}, $class, $orig; return "<$ret>" if defined $ret; return undef; } }
<40> <40><41><42> Use of uninitialized value in say at proxy_tiehash.pl line 21. <40><42> Use of uninitialized value in say at proxy_tiehash.pl line 25. 4042
Cheers Rolf
(addicted to the Perl Programming Language :)
see Wikisyntax for the Monastery
°) this smells like internally causing a recursive data structure
²) OK I got it https://perldoc.perl.org/perltie#The-untie-Gotcha, untie is normally supposed to trigger DESTROY, but inf there are still other refs to the underlying $object DESTROY can't be triggered. In my case it's actually better not to trigger DESTROY and better to silence the warning altogether.
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: using TIEHASH as wrapper/proxy, while avoiding recursion and warnings
by Corion (Patriarch) on Apr 21, 2024 at 18:16 UTC | |
by LanX (Saint) on Apr 21, 2024 at 18:35 UTC | |
Re: using TIEHASH as wrapper/proxy, while avoiding recursion and warnings
by haukex (Archbishop) on Apr 22, 2024 at 10:01 UTC | |
by LanX (Saint) on Apr 22, 2024 at 10:52 UTC | |
by haukex (Archbishop) on Apr 22, 2024 at 13:29 UTC |