Search code examples
perlhash-of-hashes

Perl Hash of Hash


So I am trying to use a Perl HoH and push some values into an array from the HoH.

Here is a portion of the code to better explain;

my $hoh = (
antenna_included=>{
    "1" => '1 MultiBand Antenna',
    "2" =>'2 Multiband Antennas',
    "3" =>'1 MultiBand Antenna & 2 WiFi Antennas',
    "4" =>'2 Multiband Cellular Antennas & 2 WiFi Antennas',
    "N" =>'No Antennas Included',
    },
ip_rating=>{
    I6 => 'IP 64',
    CD => 'Intrinsically Safe, Class 1 Div 2, IP 64',
    NI => 'No',
    });

foreach $group ( sort keys %hoh ) {
    foreach $spec ( sort keys %{ $hoh{$group} } ) {   
        print "$spec=>$hoh{$group}{$spec}\n";
    }

    print "what part is it: ";
    my $input = <STDIN>;
    chomp $input;

    if ( exists $hoh{$group} ) {
        print "$hoh{$spec}\n";                #this is the problematic line.  
    }
    else {
    print "not a match!\n";
    }
}

Basically the goal of this script is to loop through the HoH, but throughout each block of hash it gives STDIN, then you type in the key, and then then I want to push the value of that element into an array. (Right now the code just says print for debugging).

I have tried

$hoh{$group}{$spec}
$hoh{$group}
$hoh{$group}->{$spec}

For $hoh{$group} I get HASH(0x6ff920) and all of the other values it is just blank, no error.

Any thoughts? Thank you


Solution

  • Use the -> operator.

    Everything underneath the HoH is a hashref, and accessing elements of those requires the -> operator. (Technically, you have a "hash of hashref" not a "hash of hash," since such a thing isn't possible.)

    See the perlref docs for details about references.

    $hoh{$group}->{$spec}
    

    UPDATE

    Here's a modified version of your program. The differences are:

    • The initial declaration of %hoh is done with the hash variable %hoh, not the scalar variable, $hoh. Assigning the initializing list to $hoh would result in the last element of the list being assigned to the variable, in this case, the hashref corresponding to ip_rating. This is almost certainly not what you want.
    • Attempting to access an element of $hoh{$group} requires the -> operator, like `$hoh{$group}->{$spec}.
    • The problem area probably needs to be checking for the existence of $hoh{$group}->{$input}. If it doesn't exist, the input isn't valid, which is what the message suggests.

    You just need to understand the difference between a hash and a hashref (similar to the difference between an array and an arrayref) and realize that hashes and arrays cannot be elements of other hashes or arrays. Hashrefs and arrayrefs can be elements of other data structures, because only scalars can be contained within another data structure. Hashes and arrays are not scalars, but references are scalars (including hashref, arrayrefs, coderefs, and even scalarrefs) and are necessary to create any sort of complex, nested data structure.


    my %hoh = (
        antenna_included=>{
            "1" => '1 MultiBand Antenna',
            "2" =>'2 Multiband Antennas',
            "3" =>'1 MultiBand Antenna & 2 WiFi Antennas',
            "4" =>'2 Multiband Cellular Antennas & 2 WiFi Antennas',
            "N" =>'No Antennas Included',
        },
        ip_rating=>{
            I6 => 'IP 64',
            CD => 'Intrinsically Safe, Class 1 Div 2, IP 64',
            NI => 'No',
        });
    
    foreach $group ( sort keys %hoh ) {
        foreach $spec ( sort keys %{ $hoh{$group} } ) {   
            print "$spec=>$hoh{$group}->{$spec}\n";
        }
    
        print "what part is it: ";
        my $input = <STDIN>;
        chomp $input;
    
        if ( exists $hoh{$group}->{$input} ) {
            print $hoh{$group}->{$input}."\n";
        }
        else {
            print "not a match!\n";
        }
    }