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

Minimal example exhibiting a double reference autovivification trick (learnt from Brian McCauley in a clpmisc thread) to convert a list of structured strings as that below the __END__ token to a complex data structure as that illustrated by the output of the program. More details follow.
#!/usr/bin/perl use strict; use warnings; use Data::Dumper; my %dirhash; while (<DATA>) { chomp; my $last=\\%dirhash; $last=\$$last->{$_} for split qr|/|; } print Dumper \%dirhash; __END__ /file.txt /a/file.txt /a/b/c /a/b/c/file.txt /z/m/w/file.txt

Replies are listed 'Best First'.
Re: Autovivification trick
by blazar (Canon) on Aug 12, 2006 at 10:56 UTC

    Some more details: in this post someone asked how to "take strings like:"

    /file.txt /a/file.txt /a/b/c /a/b/c/file.txt /z/m/w/file.txt

    and "produce something like:"

    %dir_hash( 'file.txt' => '', 'a' => { 'file.txt' => '', 'b' => { 'c' => { 'file.txt'
    [snip]

    In my reply I pointed out that there should be a module designed for exactly this kind of things, which I still fail to remember. (Hey, anyone here? Update: It's Data::Diver, thanks to tye!) But first of all I provided a minimal example to accomplish not exactly the same task, but a very close one; the original code is as follows:

    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my %dirhash; while (<DATA>) { chomp; my $last=\%dirhash; $last=$last->{$_} ||= {} for split qr|/|; } print Dumper \%dirhash; __END__ /file.txt /a/file.txt /a/b/c /a/b/c/file.txt /z/m/w/file.txt

    In it I have to compensate for perl not autovivifying in this case. Then Brian McCauley provided an alternative way, precisely suggesting that one do

    my $last=\\%dirhash; $last=\$$last->{$_} for split qr|/|;

    Instead, which is the Autovivification trick I'm "advertising" here.

      there should be a module designed for exactly this kind of things
      The only thing I found (during my admittedly limited search) was Data::Hierarchy - could that have been the one you were thinking of? It appears to be somewhat specialized and may not quite satisfy the same requirements that your snippet does, but it's the closest thing that I found.

Re: Autovivification trick
by polettix (Vicar) on Aug 12, 2006 at 19:14 UTC
    You probably read this, I'm not sure there's a module for this.

    Update: this post was actually inteded as a reply to Re: Autovivification trick, sorry for mis-clicking.

    Flavio
    perl -ple'$_=reverse' <<<ti.xittelop@oivalf

    Don't fool yourself.
      You probably read this, I'm not sure there's a module for this.

      No, that was not it. Indeed I had never read it. I can't have imagined having seen a module used for this kinda stuff, though. I'm confident I actually did. It must have been just a few days ago.

Re: Autovivification trick
by planetscape (Chancellor) on Aug 13, 2006 at 22:06 UTC

    Thanks for this. In my admittedly limited experience to date, I'd only ever thought of autovivification as a Bad Thing™. Something to be avoided at all costs. How refreshing, in the meantime, to have come across such wonderful and creative counterexamples in nodes such as yours, as well as tlm's "BUG" and injunjoel's The Uniqueness of hashes. :-)

    planetscape
Re: Autovivification trick
by ikegami (Patriarch) on Aug 13, 2006 at 22:52 UTC

    I'm not sure the diminished readabilty brought on by a second level of indirection is worth avoiding the use of ||= {}.

    However, its use is localized, so one can understand the function of the code (through comments) without having to understand the trick.

Re: Autovivification trick (old)
by tye (Sage) on Aug 15, 2006 at 05:23 UTC

    Dog, I was doing that back in 2000. Or you can just use Data::Diver. (:

    - tye        

      Dog, I was doing that back in 2000

      Didn't know. Just discovered it. Thought it was interesting enough to deserve an "ad".

      Or you can just use Data::Diver. (:

      It's exactly the module I was thinking of.