This is the expected and intuitive behavior of a tied hash to handle $h{a}++
:
$ perl -E'
sub DESTROY {}
sub AUTOLOAD { say "$AUTOLOAD @_"; bless {} }
tie %h, main;
$h{a}++;
'
main::TIEHASH main
main::FETCH main=HASH(0x7fb6c982a188) a
main::STORE main=HASH(0x7fb6c982a188) a 140423041558889
This is also expected to handle a nested case $h{a}{b}++
, however I can't figure out why, nor, most importantly, how to override this behavior:
$ perl -E'
sub DESTROY {}
sub AUTOLOAD { say "$AUTOLOAD @_"; bless {} }
tie %h, main;
$h{a}{b}++;
'
main::TIEHASH main
main::FETCH main=HASH(0x7fbff102a188) a
I've stumbled upon this while testing the Tie::CHI. It is clearly capable of storing complex objects:
$ perl -MDateTime -MTie::CHI -E'
tie %c, "Tie::CHI", { driver => "File", root_dir => "." };
$c{a} = DateTime->now;
'
And Perl is capable of retrieving any data from the deeply nested structures, also:
print Dumper $c{json}->{results}[0]{geometry}{location};
But storing inside nested structures won't work in any tie()'d hash:
$c{json}->{results}[0]{geometry}{location} = [0, 0];
Could Tie::CHI be patched to handle this case with more DWIMmery? If not, what's the alternative?
Do you realize that
$h{a}{b}
is exactly the same thing as
$h{a}->{b}
and that is consists of two separate hash lookups? It's basically the same thing as
my $anon = $h{a};
$anon->{b}
You want %{ $h{a} }
to be a tied hash, but $h{a}
(FETCH
) returned a reference to an untied hash. Change it to return a tied hash.
$ perl -E'
sub DESTROY {}
sub FETCH { say "FETCH @_"; tie my %h, main; \%h; }
sub AUTOLOAD { say "$AUTOLOAD @_"; bless {} }
tie %h, main;
$h{a}{b}++;
'
main::TIEHASH main
FETCH main=HASH(0x8006c030) a
main::TIEHASH main
FETCH main=HASH(0x80071e28) b
main::TIEHASH main
main::STORE main=HASH(0x80071e28) b 2147952185