Let's say I want to use Tie::Hash to have a temporary wrapper around an existent hash until I untie.

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.

I'm sure I could kind of avoid all this by copying all data of the original hash when constructing the tie inside TIEHASH, but this seems like a waste of resources.

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

UPDATES

°) 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.


In reply to using TIEHASH as wrapper/proxy, while avoiding recursion and warnings by LanX

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.