By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
437,693 Members | 1,972 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 437,693 IT Pros & Developers. It's quick & easy.

Need help printing a reference to a hash of hashes

numberwhun
Expert Mod 2.5K+
P: 3,503
Hello all!

I am working on trying to figure out how to print out a hash of hashes. How the hash in the code is defined below is very similar to how the hash is defined in the script I am working with. (Yes, this is for work so I cannot share the actual code, sorry).

I was using this web page as a reference for figuring this out as it has been of great assistance before, but for some reason, the code below prints out NOTHING.

Why? I am not sure but I am hopeful that someone can tell me why and what I am doing wrong.

Expand|Select|Wrap|Line Numbers
  1. use strict;
  2. use warnings;
  3.  
  4. my %hash1;
  5. my $hash2;
  6.  
  7.  
  8. $hash2 = 1;
  9.  
  10. $hash1{$hash2}{key1} = 1;
  11. $hash1{$hash2}{key2} = 2;
  12. $hash1{$hash2}{key3} = 3;
  13.  
  14. for my $keys1 (keys %$hash1){
  15.     for my $keys2 (keys %{hash1->{$keys1}}){
  16.         print "The value of hash1->$keys1->$keys2 is:  $hash1->{$keys1}{$keys2}\n"
  17.     }
  18. }
  19.  
Thanks in advance for any and all help!

Best regards,

Jeff
Jul 24 '08 #1
Share this Question
Share on Google+
7 Replies


eWish
Expert 100+
P: 971
I am certain that Kevin will enlighten us both, but here is one that I have done in the past.
Expand|Select|Wrap|Line Numbers
  1.     # Print each of the categories
  2.     foreach my $category ( sort { keys %{ $product_data{$b} } <=> keys %{ $product_data{$a} } } keys %product_data ) {
  3.         print qq~<ul><li>$category</li>~;
  4.  
  5.             # Print each of the sub-categories (1 level deep only)
  6.             for my $sub_category ( sort { $_{$a} <=> $_{$b} }  keys %{ $product_data{$category} } )  {
  7.                 print qq~<ul><li>$sub_category</li><ul>~; 
  8.  
  9.                 # Print each of the product names of the sub-categories
  10.                 for my $product_name(@{$product_data{$category}{$sub_category}}) {
  11.                     print qq~<li>$product_name</li>~;
  12.                 }
  13.                 print qq~</ul></ul>~;
  14.              }
  15.              print qq~</ul>~;
  16.     }
--Kevin
Jul 24 '08 #2

KevinADC
Expert 2.5K+
P: 4,059
Hello all!

I am working on trying to figure out how to print out a hash of hashes. How the hash in the code is defined below is very similar to how the hash is defined in the script I am working with. (Yes, this is for work so I cannot share the actual code, sorry).

I was using this web page as a reference for figuring this out as it has been of great assistance before, but for some reason, the code below prints out NOTHING.

Why? I am not sure but I am hopeful that someone can tell me why and what I am doing wrong.

Expand|Select|Wrap|Line Numbers
  1. use strict;
  2. use warnings;
  3.  
  4. my %hash1;
  5. my $hash2;
  6.  
  7.  
  8. $hash2 = 1;
  9.  
  10. $hash1{$hash2}{key1} = 1;
  11. $hash1{$hash2}{key2} = 2;
  12. $hash1{$hash2}{key3} = 3;
  13.  
  14. for my $keys1 (keys %$hash1){
  15.     for my $keys2 (keys %{hash1->{$keys1}}){
  16.     }
  17. }
  18.  
Thanks in advance for any and all help!

Best regards,

Jeff
Did you run the code with "strict" on? It should produce these errors:

Global symbol "$hash1" requires explicit package name at script line 14.
Can't use bareword ("hash1") as a HASH ref while "strict refs" in use at script line 15.


The biggest problem is that %hash1 is not a reference to a hash, it is a hash (of hashes). Line 15 also has a syntax error, "hash1" should be "$hash1".

Here is the code corrected:

Expand|Select|Wrap|Line Numbers
  1. use strict;
  2. use warnings;
  3.  
  4. my %hash1;
  5. my $hash2;
  6.  
  7.  
  8. $hash2 = 1;
  9.  
  10. $hash1{$hash2}{key1} = 1;
  11. $hash1{$hash2}{key2} = 2;
  12. $hash1{$hash2}{key3} = 3;
  13.  
  14. for my $keys1 (keys %hash1){
  15.     for my $keys2 ( keys %{ $hash1{$keys1} } ){
  16.         print "The value of hash1->$keys1->$keys2 is:  $hash1{$keys1}{$keys2}\n"
  17.     }
  18. }
  19.  
The "print" line could also be written with the arrow operator but its not necessary:

Expand|Select|Wrap|Line Numbers
  1. print "The value of hash1->$keys1->$keys2 is:  $hash1{$keys1}->{$keys2}\n"
This is really what the original code was trying to do:

Expand|Select|Wrap|Line Numbers
  1. use strict;
  2. use warnings;
  3.  
  4. my $hash1;
  5. my $hash2;
  6.  
  7.  
  8. $hash2 = 1;
  9.  
  10. $hash1->{$hash2}->{key1} = 1;
  11. $hash1->{$hash2}->{key2} = 2;
  12. $hash1->{$hash2}->{key3} = 3;
  13.  
  14.  
  15.  
  16. for my $keys1 (keys %{$hash1}){
  17.     for my $keys2 ( keys %{ $hash1->{$keys1} } ){
  18.         print "The value of hash1->$keys1->$keys2 is:  $hash1->{$keys1}->{$keys2}\n"
  19.     }
  20. }
  21.  
Now $hash1 is a reference to a hash of hashes and not a hash of hashes.
Jul 24 '08 #3

numberwhun
Expert Mod 2.5K+
P: 3,503
Did you run the code with "strict" on? It should produce these errors:

Global symbol "$hash1" requires explicit package name at script line 14.
Can't use bareword ("hash1") as a HASH ref while "strict refs" in use at script line 15.


The biggest problem is that %hash1 is not a reference to a hash, it is a hash (of hashes). Line 15 also has a syntax error, "hash1" should be "$hash1".

Here is the code corrected:

Expand|Select|Wrap|Line Numbers
  1. use strict;
  2. use warnings;
  3.  
  4. my %hash1;
  5. my $hash2;
  6.  
  7.  
  8. $hash2 = 1;
  9.  
  10. $hash1{$hash2}{key1} = 1;
  11. $hash1{$hash2}{key2} = 2;
  12. $hash1{$hash2}{key3} = 3;
  13.  
  14. for my $keys1 (keys %hash1){
  15.     for my $keys2 ( keys %{ $hash1{$keys1} } ){
  16.         print "The value of hash1->$keys1->$keys2 is:  $hash1{$keys1}{$keys2}\n"
  17.     }
  18. }
  19.  
The "print" line could also be written with the arrow operator but its not necessary:

Expand|Select|Wrap|Line Numbers
  1. print "The value of hash1->$keys1->$keys2 is:  $hash1{$keys1}->{$keys2}\n"
This is really what the original code was trying to do:

Expand|Select|Wrap|Line Numbers
  1. use strict;
  2. use warnings;
  3.  
  4. my $hash1;
  5. my $hash2;
  6.  
  7.  
  8. $hash2 = 1;
  9.  
  10. $hash1->{$hash2}->{key1} = 1;
  11. $hash1->{$hash2}->{key2} = 2;
  12. $hash1->{$hash2}->{key3} = 3;
  13.  
  14.  
  15.  
  16. for my $keys1 (keys %{$hash1}){
  17.     for my $keys2 ( keys %{ $hash1->{$keys1} } ){
  18.         print "The value of hash1->$keys1->$keys2 is:  $hash1->{$keys1}->{$keys2}\n"
  19.     }
  20. }
  21.  
Now $hash1 is a reference to a hash of hashes and not a hash of hashes.
Interesting. Gotta practice up with these. Thanks Kevin, it worked!

Regards,

Jeff
Jul 24 '08 #4

KevinADC
Expert 2.5K+
P: 4,059
It seems to be a common source of confusion. Just keep in mind if you decalre a hash like this:

Expand|Select|Wrap|Line Numbers
  1. %hash = (key => 'value');
or:

Expand|Select|Wrap|Line Numbers
  1. $hash{key} = 'value'; 
it is just a regular hash regardless of whatever is in the hash. Same is true with an array. Now the data stored in the hash/array could be references to other things, but the main hash/array is not.

These would be references to hashes or arrays:

Expand|Select|Wrap|Line Numbers
  1. $hash = {foo => 'bar'};
  2. $array = [qw(foo bar)];
The difference is of course using a scalar on the left side and the respective brackets on the right side.
Jul 24 '08 #5

P: 14
Jeff,

You can print hash of hash easily using Dumper.
Data::Dumper is one module


-Chiku
Jul 25 '08 #6

KevinADC
Expert 2.5K+
P: 4,059
Jeff,

You can print hash of hash easily using Dumper.
Data::Dumper is one module


-Chiku
This is true, and Jeff is aware of that, he could have used it maybe to pin point the problems in his own code. Good suggestion to use Data::Dumper.
Jul 25 '08 #7

numberwhun
Expert Mod 2.5K+
P: 3,503
This is true, and Jeff is aware of that, he could have used it maybe to pin point the problems in his own code. Good suggestion to use Data::Dumper.
I do know that I can print it using Data::Dumper, but unfortunately the situation does not allow for the inclusion of new modules (that situation being that this is work related).

See, the software I am working with is distributed to the field machines only after they have been converted to executable binaries using perl2exe. It was already setup to include a specific set of modules.

Sure, modules can be added, but it not something I want to undertake at this time when I can do it without it. Thanks for the suggestion though, as Kevin said, it was definitely a good one.

Regards,

Jeff
Jul 25 '08 #8

Post your reply

Sign in to post your reply or Sign up for a free account.