in reply to setting hash keys by array

Here's how I usually do it:
use Data::Dumper; my @keys = qw( this that those ); my $node = \\my %hash; # edit: this was my old way... # my $i = 0; # $node = \$$node->{$keys[$i++]} while $i < @keys; # thanks to Juerd $node = \$$node->{$_} for @keys; $$node = "value"; print Dumper \%hash;

_____________________________________________________
Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a job (NYC-area)
s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

Replies are listed 'Best First'.
Re: Re: setting hash keys by array
by Juerd (Abbot) on Sep 09, 2002 at 16:53 UTC

    $node = \$$node->{$keys[$i++]} while $i < @keys;

    ++. IMHO, this is the only sane approach. But why not $node = \$$node->{$_} for @keys;?

    Update
    Reputation: 41, it says. MADNESS. I only suggested the use of for LIST instead of explicitly using an index variable. It's a style related comment. Why on earth did you people upvote this THIS MUCH? There are better nodes getting lower scores. Vote for those. ++ japhy, ++ demerphq for they did the work. I only complained about style.

    - Yes, I reinvent wheels.
    - Spam: Visit eurotraQ.
    

      Nice stuff to both you and japhy

      While trying to grok that code I stumbled on an interesting different approach... Its not suitable for building a tree from many lists, but is suitable for building a HOH out of a single list:

      use Data::Dumper; my @keys = qw( this that those ); my $node='value'; $node={$_=>$node} foreach reverse @keys; print Dumper $node; __END__ $VAR1 = { 'this' => { 'that' => { 'those' => 'value' } } };

      --- demerphq
      my friends call me, usually because I'm late....

      Why not:

      my @chain = qw/a b c d/; my %hash; sub foo(\%@){ local $_ = shift; $_ = $_->{scalar shift} = {} while @_; } foo %hash => @chain;

      ? it's becoming obfuscated ...

      --
      http://fruiture.de
      My mistake -- I lifted it from old code of mine. Recent versions use your suggested alteration.

      _____________________________________________________
      Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a job (NYC-area)
      s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

Re: Re: setting hash keys by array
by hotshot (Prior) on Sep 10, 2002 at 06:58 UTC
    Thanks for your answer !!, but can you give me a little explenation, what exactly it does and the syntax (especially lines 3)
    1) use Data::Dumper; 2) my @keys = qw( this that those ); 3) my $node = \\my %hash; 4) $node = \$$node->{$_} for @keys; 5) $$node = "value"; 6) print Dumper \%hash;
    I prefer understanding this before using it.
    Thanks

    Hotshot
      Yeah this is a nasty cryptic and totally groovy way to do things. I think I understand how it works, let see if I am right...
      my $node=\\my %hash;
      This sets $node to be a reference to a reference to %hash.
      $node = \$$node->{$_} for @keys;
      So this says to make node become equal to a reference to the slot $_ in the current hashref that $node references (foreach element in the list). It might be clearer to write it like so:
      $node = \(${$node}->{$_})
      Basically the idea of this is to take advantage of perls autovivification. The double reference is a nice way to ensure that we are always pointed at the slot that holds the previous key. If that value is undef, then it will be autovivified when it is used as a reference.

      $$node = "value";
      Stick the final value in.

      Cool eh? juerd++ and japhy++

      --- demerphq
      my friends call me, usually because I'm late....

Re: Re: setting hash keys by array
by shotgunefx (Parson) on Sep 09, 2002 at 17:09 UTC
    Here's how I usually do it:

    Is this something that you usually need to do? :P

    -Lee

    "To be civilized is to deny one's nature."
      Har har. First, you misunderstand my sentence. Second, it's done more often than you might think. I have a friend at RiskGrades who asked for some help setting up a hash in this way. She gets a list of keys, and needs to build up a hash (of hashes)+ based on those keys.

      _____________________________________________________
      Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a job (NYC-area)
      s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

        I use nested structures all the time. I just can't see too many applications of taking a random list and creating a HoHoH..etc out of it.

        ++ for the best solution.

        I still wonder if this is the question the poster was asking or didn't know how to write a hash slice. :)

        -Lee

        "To be civilized is to deny one's nature."