For certain types of programming, generally things that I expect Perl to be great for, I encounter one big annoyance: complex data structure access. Specifically, consider a case where you have a deeply nested structure. The easiest way to implement this in module-less Perl is to use nested hashes-of-hashes. But then I find myself writing code like (variable names shortened to avoid wrapping):
$cost = $h->{Locations}{$location}{Buildings}{$b}{cost};
The whole {a}{b}{c}{d}{e} thing drives me crazy, especially when compared to C's a.b.c.d style. (Of course, this example would be tough in C: Locations[0].Buildings[3].cost, perhaps? Not quite the same.) I know of several Perl modules to help with this sort of thing, but they all transform it into:
$cost = $h->Locations->$location->Buildings->$b->cost;
Which isn't much of an improvement, in my eyes -- sure, you get rid of the curly brackets, but instead you deceptively make things look like methods, and I don't want to think of every single layer in my data structure as a data accessor method. It's just data, dammit!

So I wrote a module to experiment with a different style:

$cost = $h->{"Locations.$location.Buildings.$b.cost"};
Not really very different. But somehow it feels much more satisfying to me. Just for kicks, I also implemented a method each() that, rather than doing the usual operation across one level of the HoH, it does a recursive conversion to dotted keys:
while (my ($key, $value) = $h->each) { print "$key => $value\n"; } OUTPUT: Locations.Earth.Buildings.PowerPlant.cost => 7 Locations.Earth.Buildings.PowerPlant.size => 4 Locations.Earth.Coordinates => 12.0,72.4 Locations.Squaffle.Buildings.SaltRefinery.cost => 2 . . .
The implementation is a package that you both bless and tie the constituent hash refs to, and that manufactures new objects of the same sort when needed for FETCHes and STOREs.

I have the usual naming problem (the working name is the clearly-not-acceptable Struct.pm; maybe Hash::Dot? It's kind of like that website, Slash::Dot.), but I'm wondering if this has already been done. It's not a particularly brilliant idea, and probably many of you will find it revolting. In my admittedly cursory scan of search.cpan.org, I couldn't find anything, but it's a tough one to search for. Has anyone heard of such a thing?

Additionally, who else runs into this problem? Is there some alternative approach that I should be considering? I really don't want to use a database for this -- it's a huge amount of overhead for simply wanting to be able to use nested data structures a little more comfortably. Although if it were transparent and fast, I wouldn't mind.

Considered by radiantmatrix: "Retitle 'C-style dot notation for complex hash access' for better searching" (Keep/Edit/Delete vote = 12/18/0)
Unconsidered by davido: No clear vote consensus after two days.


In reply to Dotted hash access by sfink

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.