There is an example in the pod for Data::Rmap that shows how to use it's rmap_to() function to traverse a structure maintaining local state (the path through the hashes). It could be used as a starting point to create a custom iterator function.

# Traverse a tree using localize state $tree = [ one => two => [ three_one => three_two => [ three_three_one => ], three_four => ], four => [ [ five_one_one => ], ], ]; @path = ('q'); rmap_to { if(ref $_) { local(@path) = (@path, 1); # ARRAY adds a new level to the pa +th $_[0]->recurse(); # does stuff within local(@path)'s scope } else { print join('.', @path), " = $_ \n"; # show the scalar's path } $path[-1]++; # bump last element (even when it was an aref) } ARRAY|VALUE, $tree; # OUTPUT # q.1 = one # q.2 = two # q.3.1 = three_one # q.3.2 = three_two # q.3.3.1 = three_three_one # q.3.4 = three_four # q.4 = four # q.5.1.1 = five_one_one

This would involve writing your own function that wrapped code something similar to the above, but localise the keys on the fly. You would pass a callback (function or block) to the wrapper function, and it would call your code, with the appropriate variables ($env, $platform, $host, $target etc.) set and localised. You write this once the call with different callbacks each time you need to iterate the structure. If this idea interests you, but you need a bit more info on implementing it /msg me.

The other thought that crossed my mind was if you only ever access this structure through iteration, rather than individual direct accesses, then a HoH is probably the wrong structure. An AoH would be easier to use in that case. It might look something like this (pseudo-code):

my @servers = ( { type => production | development, env => Windows | unix | Database, hostname => the hostname targets => [ name1 => [ #total, #free ]. name2 => [ #total, #free ], ... ], }, { type => production | development, env => Windows | unix | Database, hostname => the hostname targets => [ name1 => [ #total, #free ]. name2 => [ #total, #free ], ... ], }, ... );

And to iterate it:

use constant { TOTAL => 0, FREE => 1 }; for my @server ( @servers ) { printf "Server: %s type:%s Env: %s\n", $server->{ hostname }, $server->{ type }, $server->{ env }; for my $target ( @{ $server->{ targets } } ) { printf "\tTotal: %d Free: %d\n", @{ $target }[ TOTAL, FREE ]; } }

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

In reply to Re: Help with Hash of hashes, is there a better way? by BrowserUk
in thread Help with Hash of hashes, is there a better way? by TeraMarv

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.