http://www.perlmonks.org?node_id=234604


in reply to •Re: How to tie multilevel (multidimensional) hash?
in thread How to tie multilevel (multidimensional) hash?

Well, merlyn, I guess my lifetime's over. Regexp::Common didn't have the answer in itself, but it did provide me the clue I needed. I'm sorry to have doubted it (well, to be honest, I just didn't see it until that flash of inspiration hit me, which is to say that the FETCH() must perform a nested tie as well as the STORE()). Here's my solution (some cleanup is still to be done as testing continues, but it works!):

test.pl

#! /users/michwong/perl/bin/perl #! /users/michwong/perl/bin/perl -d:ptkdb use lib qw( . ); use MultiHash; tie %$hash, "MultiHash"; $hash->{ x }{ y } = 10; print $hash->{ x }{ y }, "\n"; $hash->{ x }{ z } = 20; print $hash->{ x }{ z }, "\n"; </code>

MultiHash.pm

package MultiHash; sub TIEHASH { my ($class) = map { ref || $_ } shift; my $level = shift || 0; return bless { level => $level, data => {}, }, $class; } sub FETCH { my $self = shift; my $key = shift; if( exists( $self->{ data }{ $key } )) { return $self->{ data }{ $key }; } else { my $node = {}; tie %$node, "MultiHash"; $self->{ data }{ $key } = $node; return; } } sub STORE { my $self = shift; my $key = shift; my $value = shift; RECURSE_CASE: { # ===== MULTIDIMENSIONAL HASH if( UNIVERSAL::isa( $value, 'HASH' )) { if( exists $self->{ data }{ $key } ) { $self->{ data }{ $key } = $value; } else { my $node = {}; tie %$node, "MultiHash"; $self->{ data }{ $key } = $node; } last RECURSE_CASE; } if( UNIVERSAL::isa( $value, 'MultiHash' )) { if( exists $self->{ data }{ $key } ) { $self->{ data }{ $key } = $value; } else { my $node = {}; tie %$node, "MultiHash"; $self->{ data }{ $key } = $node; } last RECURSE_CASE; } if( UNIVERSAL::isa( $value, 'SCALAR' )) { $self->{ data }; last RECURSE_CASE; } } return $value; } sub DELETE { my $self = shift; my $key = shift } sub FIRSTKEY { my $self = shift; my $temp = keys %{ $self->{ data }}; return scalar each %{ $self->{ data }}; } sub NEXTKEY { my $self = shift; return scalar each %{ $self->{ data }}; } 1;