0
votes

I'm a bit confused on perl hashes.

I know that you can create a hash by calling:

my %hashTable;

$hashTable("Key") = "Value"

later on, if you want to retrieve the value, you can do

print $hashTable("Key")

However, I'm confused on this for loop

foreach (keys %{$hashTable{"key"}})
{
    print $_
}

without the %{$hashTable{"key"}}, it looks that it is going to print out each of the keys, but what happens if you do a % in front of a hash table?

I tried to test out this function, by giving it a key called "key", it would give me an error: can't use string ("key") as a hash reference. Is there something to do with multi-dimensional hash tables?

2
The only way I see that this could work is if the hash hashTable contained itself, as values, hashs. So $hashTable{"key"} would return a hash. - AntonH
do you mean that there's another hash table contained in one of the key value pairs? - user1157751
Yes. That in the hash hashTable, with the key "key", that the value is itself a hash (you can mix what the value contains, whether a scalar, array or hash). And the line keys %{$hashTable{"key"}} returns the keys from that value hash. - AntonH
AHHHH!!! Now I get it. Thanks for your help! - user1157751
Yes, your iterating on the keys of a subhash. Check out perldsc - Perl Data Structures Cookbook for more information on such structures. - Miller

2 Answers

4
votes

What's happening is that you have a hash, called %hashTable. It has a value with the key key, which has for a value another hash table.

So the code:

foreach (keys %{$hashTable{"key"}})
{
    print $_
}

is looping through that second hash, and printing out the keys that it contains.

Here is an example using the documentation link that Miller provided:

#!/usr/bin/perl

use strict;
use warnings;

my %HoH = (
    flintstones => {
        lead => "fred",
        pal => "barney",
    },
    jetsons => {
        lead => "george",
        wife => "jane",
        "his boy" => "elroy",
    },
    simpsons => {
        lead => "homer",
        wife => "marge",
        kid => "bart",
    },
);

foreach (keys %{$HoH{"flintstones"}})
{
    print $_."\n";
}

This has the output:

lead
pal
1
votes

Imagine your hashTable as

key1:           <-+
    value1        |
key2:             |
    value2        += this is your hashTable, with 3x key/value
key3:             |
    value3      <-+

Now chaange the value for the keyN - so, it will not contain a scalar value, but one another hash, like:

key1:
    subkey1a: subval1a      <-+ this "HASH" is the value for the "key1".
    subkey1b: subval1b      <-|
key2:
    subkey2a: subval2a
key3:
    subkey3a: subval3a
    subkey3b: subval3b
    subkey3c: subval3c