I use the SNAP (Stacked Nodes Affect Parent) method. I use it for my YAPE modules. The process is rather simple. Make two variables refer to the same reference, and you create an array for stacking.
my $node = my $tree = []; my @stack;
You never modify $tree directly -- you do all the manipulation on $node, and when you need to recurse, you add a new "field" to $node; then you push the $node onto the @stack, and then you set $node equal to the field:
if ($token eq '(') { push @{ $node }, []; push @stack, $node; $node = $node->[-1]; # the new empty array ref }
When you return from the recursion, you get the top value from the @stack:
if ($token eq ')') { $node = pop @stack; }
Now, $node contains what it was before, PLUS any modifications to that empty array reference. And because $node and $tree refer to the same data, modifying the data in $node modifies $tree.

It's important to realize that saying:

$a = $b = []; $a = 2;
does not affect $b in any way. It's the changing of the data referred to by $a that affects $b.

Without further ado, here is my implementation of a directory tree structure, using SNAP.

#!/usr/bin/perl -w use File::Find; use Data::Dumper; use strict; $Data::Dumper::Indent = 1; build_tree(my $tree, shift); print Dumper $tree; { sub build_tree { my $node = $_[0] = {}; my @s; find( sub { # fixed 'if' => 'while' -- thanks Rudif $node = (pop @s)->[1] while @s and $File::Find::dir ne $s[-1][0] +; return $node->{$_} = -s if -f; push @s, [ $File::Find::name, $node ]; $node = $node->{$_} = {}; }, $_[1]); $_[0]{$_[1]} = delete $_[0]{'.'}; } }
The recursion is not handled by me, it's handled by find(), so I had to kludge my way into faking the start and end of a recursion. But it works.

japhy -- Perl and Regex Hacker

In reply to Re: How to map a directory tree to a perl hash tree by japhy
in thread How to map a directory tree to a perl hash tree by Rudif

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.