gdig321 has asked for the wisdom of the Perl Monks concerning the following question:

fellow monks: a little background before the question:

1) say i have a hash like this:
%goodhash = ( red => '1', blue => '2', green => '3', ); @colors = qw(red blue green); print $fh join("|", @hash{@colors}), "\n"

--->writes a line "1|2|3\n" no problem

2) now the question, what if i have a hash of hashes
say something like
$evilhash{$id} = { red => '1', blue => '2', green => '3', }; @colors = qw(red blue green);

but it complains about undef ARRAY ref when i do
print $fh join("|", @evilhash{$id}{@colors}), "\n" or this @{$evilhash{$id}}{@colors}


read thru the perldsc,etc but no success

any advice please?

g

Replies are listed 'Best First'.
Re: print hash of hashes as lists
by meonkeys (Chaplain) on May 29, 2001 at 05:27 UTC
    Try the following:
    $evilhash->{1} = { red => 1, blue => 2, green => 3, }; my @colors = qw( red blue green ); print join("|", @{$evilhash->{1}}{@colors}), "\n";

    The data structure you specified, the hash of hashes, would look like this:
    $evilhash = { '1' => { 'blue' => 2, 'green' => 3, 'red' => 1 } };
    (thank you Data::Dumper)

    To get to that "1" hash, you have to explicitly dereference "1" with the "->" operator because "1" is a reference to an anonymous hash. I found this in perldsc.
      But that's doing the same thing. From perldsc

      If you want to get at the thing a reference is referring to, then you have to do this yourself using either prefix typing indicators, like
      ${$blah}, @{$blah}, @{$blah[$i]} , or else postfix pointer arrows, like
      $a->[3], $h->{fred}, <i>or even</i> $ob->method()->[3].

      If you set the hash:
      $evilhash->{1} = { ...
      and deref:
      @{$evilhash->{1}}{@colors})
      Then that's the same as setting the hash:
      $evilhash{$id} = { ...
      and deref:
      @{$evilhash{$id}}{@colors}

      No?

        First, to clarify, the answer I posted for gdig321 was not intended to represent the only Way to do it (see TMTOWTDI). I'm just used to using the -> operator.

        The two examples you gave are slightly different. First:
        $evilhash->{1} = {}
        makes $evilhash a reference to an anonymous hash. The anonymous hash has one key, "1", with an empty hashref as the value corresponding with this key.
        $evilhash{1} = {}
        makes %evilhash, a true hash, which has one key, "1", with an empty hashref as the value corresponding with this key.

        Your two examples are correctly written and will produce the same result, I agree. Thanks for the clarification,

        -Adam
Re: print hash of hashes as lists
by mr.nick (Chaplain) on May 29, 2001 at 03:45 UTC
    For your specific problem
    print join("|",@{$evilhash{$id}}{@colors}),"\n";
    works like your first example.

    Update: I think I need to read up on my hash slices.