in reply to eval on hash

Based on (tye)Re: varying length multi-dimensional hashes:

sub derefHashTree { my( $hv, @keys )= @_; my $ref= \$hv; for my $key ( @keys ) { $ref= \$$ref->{$key}; } return $$ref; } my %hash1; $hash1{key1}{key2}{key3}{A} = "hello"; $hash1{key1}{key2}{key3}{B} = "bye"; my $new_hash = \%hash1; my @keys= qw( key1 key2 key3 ); foreach( keys %{ derefHashTree($new_hash,@keys) } ) { print "$_\n"; }
Note that you can return $ref; instead of $$ref if you want to modify the indicated value instead of just fetching it.

                - tye

Replies are listed 'Best First'.
Re: Re: eval on hash (use \\)
by Anonymous Monk on Apr 09, 2003 at 17:51 UTC
    To get a better understanding of what I could do with this piece of code, I tried to modify it as follows only to get this error: "delete argument is not a HASH or ARRAY element or slice at ./test2.pl line 29"
    #!/usr/bin/perl -w use strict; use Data::Dumper; sub derefHashTree { my( $hv, @keys )= @_; my $ref= \$hv; for my $key ( @keys ) { $ref= \$$ref->{$key}; } return $ref; } my %hash1; $hash1{key1}{key2}{key3}{A} = "hello"; $hash1{key1}{key2}{key3}{B} = "bye"; my $new_hash = \%hash1; my @keys= qw( key1 key2 key3 A); #foreach( keys %{ derefHashTree($new_hash,@keys) } ) { # print "$_\n"; #} my $new_ref = derefHashTree($new_hash,@keys); delete $new_ref; print Dumper(\%hash1);

    I've also tried "delete $$new_ref", "delete ${$new_ref}", "delete %{$new_ref}"

    Thanks

      You need to delay the last deref:

      my @keys= qw( key1 key2 key3 A ); my $last= pop(@keys); delete derefHashTree($new_hash,@keys)->{$last};

                      - tye
      Read delete for more info. You might be trying to use undef instead.

      ------
      We are the carpenters and bricklayers of the Information Age.

      Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

      Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.