in reply to descending a tree of hash references

Amoe,

It's not clear to me what you are trying to do. After you have traversed the hash refs as you have shown and $nodule has the hash ref of $structure->{stuff}{hierarchy}{album}, then changing $nodule->{$target} will have the effect of changing $structure->{stuff}{hierarchy}{album}{$target}.

Some more code or context would be useful.

YuckFoo

Update: Some code to traverse a list of hash keys and change the last one. HTH.

#!/usr/bin/perl use strict; my ($hash); $hash->{one}{two}{three} = 'before'; print "$hash->{one}{two}{three}\n"; changehash($hash, [qw(one two three)], 'after'); print "$hash->{one}{two}{three}\n"; #----------------------------------------------------------- sub changehash { my ($node, $keys, $val) = @_; my $key; my $last = pop(@{$keys}); for $key (@{$keys}) { if (defined ($node->{$key})) { $node = $node->{$key}; } else { print STDERR "Unknown key: $key\n"; return; } } if (defined ($node->{$last})) { $node->{$last} = $val } else { print STDERR "Unknown key: $last\n"; return; } }

Replies are listed 'Best First'.
Re: Re: descending a tree of hash references
by Amoe (Friar) on Feb 20, 2002 at 12:35 UTC

    Hey YuckFoo. Ready for context? Here goes...

    I'm getting a hashref from a DB_File, and unfreezing the data structure contained within with Storable. Then I traverse a user-defined path in the hashref and set a key in it, and it'll eventually get frozen back to the DB_File. An added complication (one that I should have mentioned, with hindsight :() is that if the full path doesn't exist, I have to create all the hashrefs leading up to the end - whilst still preserving everything that was in the original data structure. Here's a literal chunk of code from what I have.

    # the first element of $path is always a key in the DB_File my ($root, $tip) = (shift(@path), pop(@path)); # get old tree my $old = thaw($db{$root}); # start off at the root $nodule = $old; while (my $next_key = shift @path) { unless (exists $nodule->{$next_key}) { $nodule->{$next_key} = {}; } $nodule = $nodule->{$next_key}; } $nodule->{$tip} = $content; print Dumper($old);

    The thing is, when I print $old with Data::Dumper, I would expect it to be a structure looking like this (given that @path = ('foo', 'bar'), $tip = 'baz' and $content = 'some arbitrary data'):

    $VAR1 = {foo => {bar => {baz => 'some arbitrary data'} } };

    Instead it looks like:

    $VAR1 = undef;

    So that's what I want to achieve, and the example I gave in the question seems to be lose context in this environment, when by all rights it should work. Damn real life.



    --
    my one true love
      Amoe,

      Thanks, problem well stated. Unfortunately I couldn't reproduce the problem. I think you are not getting what you expect in $old when thawing. Try print Dumper($old) immediately after thawing.

      YuckFoo