Need help printing a reference to a hash of hashes

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • numberwhun
    Recognized Expert Moderator Specialist
    • May 2007
    • 3467

    Need help printing a reference to a hash of hashes

    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.

    Code:
    use strict;
    use warnings;
    
    my %hash1;
    my $hash2;
    
    
    $hash2 = 1;
    
    $hash1{$hash2}{key1} = 1;
    $hash1{$hash2}{key2} = 2;
    $hash1{$hash2}{key3} = 3;
    
    for my $keys1 (keys %$hash1){
    	for my $keys2 (keys %{hash1->{$keys1}}){
    		print "The value of hash1->$keys1->$keys2 is:  $hash1->{$keys1}{$keys2}\n"
    	}
    }
    Thanks in advance for any and all help!

    Best regards,

    Jeff
  • eWish
    Recognized Expert Contributor
    • Jul 2007
    • 973

    #2
    I am certain that Kevin will enlighten us both, but here is one that I have done in the past.
    Code:
    	# Print each of the categories
    	foreach my $category ( sort { keys %{ $product_data{$b} } <=> keys %{ $product_data{$a} } } keys %product_data ) {
    		print qq~<ul><li>$category</li>~;
    			
    			# Print each of the sub-categories (1 level deep only)
    			for my $sub_category ( sort { $_{$a} <=> $_{$b} }  keys %{ $product_data{$category} } )  {
    				print qq~<ul><li>$sub_category</li><ul>~; 
    				
    				# Print each of the product names of the sub-categories
    				for my $product_name(@{$product_data{$category}{$sub_category}}) {
    					print qq~<li>$product_name</li>~;
    				}
    				print qq~</ul></ul>~;
    	 		}
     			print qq~</ul>~;
    	}
    --Kevin

    Comment

    • KevinADC
      Recognized Expert Specialist
      • Jan 2007
      • 4092

      #3
      Originally posted by numberwhun
      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.

      Code:
      use strict;
      use warnings;
      
      my %hash1;
      my $hash2;
      
      
      $hash2 = 1;
      
      $hash1{$hash2}{key1} = 1;
      $hash1{$hash2}{key2} = 2;
      $hash1{$hash2}{key3} = 3;
      
      for my $keys1 (keys %$hash1){
      	for my $keys2 (keys %{hash1->{$keys1}}){
      	}
      }
      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:

      Code:
      use strict;
      use warnings;
      
      my %hash1;
      my $hash2;
      
      
      $hash2 = 1;
      
      $hash1{$hash2}{key1} = 1;
      $hash1{$hash2}{key2} = 2;
      $hash1{$hash2}{key3} = 3;
      
      for my $keys1 (keys %hash1){
      	for my $keys2 ( keys %{ $hash1{$keys1} } ){
      		print "The value of hash1->$keys1->$keys2 is:  $hash1{$keys1}{$keys2}\n"
      	}
      }
      The "print" line could also be written with the arrow operator but its not necessary:

      Code:
      print "The value of hash1->$keys1->$keys2 is:  $hash1{$keys1}->{$keys2}\n"
      This is really what the original code was trying to do:

      Code:
      use strict;
      use warnings;
      
      my $hash1;
      my $hash2;
      
      
      $hash2 = 1;
      
      $hash1->{$hash2}->{key1} = 1;
      $hash1->{$hash2}->{key2} = 2;
      $hash1->{$hash2}->{key3} = 3;
      
      
      
      for my $keys1 (keys %{$hash1}){
      	for my $keys2 ( keys %{ $hash1->{$keys1} } ){
      		print "The value of hash1->$keys1->$keys2 is:  $hash1->{$keys1}->{$keys2}\n"
      	}
      }
      Now $hash1 is a reference to a hash of hashes and not a hash of hashes.

      Comment

      • numberwhun
        Recognized Expert Moderator Specialist
        • May 2007
        • 3467

        #4
        Originally posted by KevinADC
        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:

        Code:
        use strict;
        use warnings;
        
        my %hash1;
        my $hash2;
        
        
        $hash2 = 1;
        
        $hash1{$hash2}{key1} = 1;
        $hash1{$hash2}{key2} = 2;
        $hash1{$hash2}{key3} = 3;
        
        for my $keys1 (keys %hash1){
        	for my $keys2 ( keys %{ $hash1{$keys1} } ){
        		print "The value of hash1->$keys1->$keys2 is:  $hash1{$keys1}{$keys2}\n"
        	}
        }
        The "print" line could also be written with the arrow operator but its not necessary:

        Code:
        print "The value of hash1->$keys1->$keys2 is:  $hash1{$keys1}->{$keys2}\n"
        This is really what the original code was trying to do:

        Code:
        use strict;
        use warnings;
        
        my $hash1;
        my $hash2;
        
        
        $hash2 = 1;
        
        $hash1->{$hash2}->{key1} = 1;
        $hash1->{$hash2}->{key2} = 2;
        $hash1->{$hash2}->{key3} = 3;
        
        
        
        for my $keys1 (keys %{$hash1}){
        	for my $keys2 ( keys %{ $hash1->{$keys1} } ){
        		print "The value of hash1->$keys1->$keys2 is:  $hash1->{$keys1}->{$keys2}\n"
        	}
        }
        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

        Comment

        • KevinADC
          Recognized Expert Specialist
          • Jan 2007
          • 4092

          #5
          It seems to be a common source of confusion. Just keep in mind if you decalre a hash like this:

          Code:
          %hash = (key => 'value');
          or:

          Code:
          $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:

          Code:
          $hash = {foo => 'bar'};
          $array = [qw(foo bar)];
          The difference is of course using a scalar on the left side and the respective brackets on the right side.

          Comment

          • chiku1523
            New Member
            • Jul 2008
            • 14

            #6
            Jeff,

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


            -Chiku

            Comment

            • KevinADC
              Recognized Expert Specialist
              • Jan 2007
              • 4092

              #7
              Originally posted by chiku1523
              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.

              Comment

              • numberwhun
                Recognized Expert Moderator Specialist
                • May 2007
                • 3467

                #8
                Originally posted by KevinADC
                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

                Comment

                Working...