user2688673 user2688673 - 8 months ago 18
Perl Question

Hash reference - Reuse inner hash to store and retrieve next values

I am new to Perl programming and have to work on Hash of Hashes. I am trying to reuse

variables to be dynamic in nature. And I expect the inner items to be stored in
how ever many I have added. Below is my test program snippet.

use warnings;
sub testHash {
my %outerHash = ();

my %innerHash1 = ();
my %innerHash2 = ();

$innerHash1{"key1"} = "value1";
$innerHash1{"key2"} = "value2";
$innerHash1{"key3"} = "value3";
$outerHash{"Master1"} = \%innerHash1;

$innerHash2{"key4"} = "value4";
$innerHash2{"key5"} = "value5";
$innerHash2{"key6"} = "value6";
$outerHash{"Master2"} = \%innerHash2;

#delete $innerHash1{$_};
%innerHash1 = ();
#undef %innerHash1;

$innerHash1{"key7"} = "value7";
$innerHash1{"key8"} = "value8";
$innerHash1{"key9"} = "value9";
$outerHash{"Master3"} = \%innerHash1;

foreach $outerItem (keys %outerHash){
print "\n$outerItem: ";
foreach $innerItem (keys %{$outerHash{$outerItem}}){
print "\t $innerItem = $outerHash{$outerItem}{$innerItem}";
print "\n-------------------------------------------------------";
print "\n";



Master3: key8 = value8 key7 = value7 key9 = value9
Master2: key5 = value5 key6 = value6 key4 = value4
Master1: key8 = value8 key7 = value7 key9 = value9

I understand it's taking the newer reference of
while printing the items. What is the right way to have all the right elements in
? In a real programming scenario I cannot declare n variables in advance.


You may be new to perl, but you understand the concept of pointers don't you? The code $outerHash{"Master1"} = \%innerHash1; means that "$outerHash{"Master1"} is assigned a pointer to %innerHash1". So what you're observing is correct and expected.

If you want to keep recreating %innerHash and adding it to %outerHash, you will need to do one of two things:

  • Assign by value. $outerHash{"Master1"} = {}; %{$outerHash{"Master1"}} = %innerHash1;
  • Only add %innerHash to %outerHash once per loop. Since %innerHash is redeclared within the loop, not outside of it, it goes out of scope every loop, but its contents will be kept in outerHash due to perl's reference counting. Depending on your perspective, this could be considered "trying to be too clever and potentially dangerous", but I think it's fine.