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:my $node = my $tree = []; my @stack;
When you return from the recursion, you get the top value from the @stack:if ($token eq '(') { push @{ $node }, []; push @stack, $node; $node = $node->[-1]; # the new empty array ref }
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.if ($token eq ')') { $node = pop @stack; }
It's important to realize that saying:
does not affect $b in any way. It's the changing of the data referred to by $a that affects $b.$a = $b = []; $a = 2;
Without further ado, here is my implementation of a directory tree structure, using SNAP.
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.#!/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]{'.'}; } }
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
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |