title: Recursively printing data structures in Perl
body: <p>I am currently learning Perl. I have Perl hash that contains references to hashes and arrays. The hashes and arrays may in turn contain references to other hashes/arrays. </p>
  
  <p>I wrote a subroutine to parse the hash recursively and print them with proper indentation. Though the routine works as expected, my instructor was not convinced about the readability and elegance of the below code. </p>
  
  <p>I would really appreciate to get the views of Perl experts here on possible optimization of the below code.</p>
  
  <p>Here is my complete code snippet..</p>
  
  <pre><code># Array of Arrays
  $ref_to_AoA = [
       [ "fred", "barney" ],
       [ "george", "jane", "elroy" ],
       [ "homer", "marge", "bart" ],
  ];
  
  
  #Array of Hashes
  $ref_to_AoH = [ 
  {
     husband  =&gt; "barney",
     wife     =&gt; "betty",
     son      =&gt; "bamm bamm",
  },
  {
     husband =&gt; "george",
     wife    =&gt; "jane",
     son     =&gt; "elroy",
  },
  ];
  
  # Hash of Hashes
  $ref_to_HoH = { 
      flintstones =&gt; {
          husband   =&gt; "fred",
          pal       =&gt; "barney",
      },
      jetsons =&gt; {
         husband   =&gt; "george",
         wife      =&gt; "jane",
         "his boy" =&gt; "elroy",  # Key quotes needed.
      },
      simpsons =&gt; {
         husband   =&gt; "homer",
         wife      =&gt; "marge",
         kid       =&gt; "bart",
      },
  };
  
  # Hash which contains references to arrays and hashes
  $finalHash = {
     'arrayofArrays' =&gt; $ref_to_AoA,
     'arrayofHash' =&gt; $ref_to_AoH,
     'hashofHash' =&gt; $ref_to_HoH,
  };
  
  $string = str($finalHash); 
  print "$string\n";
  
  #------------------------------------------------------------------
  sub str {
      my $hash = shift;
      my ($space, $newline, $delimiter) = @_;
      $space = "" unless (defined $space);
      $newline = "\n\n\n" unless (defined $newline);
      $delimiter = "\n--------------------------------------------" unless (defined $delimiter);
      my $str = "";
  
      for (sort keys %{$hash}) {
          my $value = $hash-&gt;{$_};
          $str .= "$newline$space$_ == $value$delimiter";
          $str .= recurseErrors($value,$space);
      }
      $str;
  }
  
  #------------------------------------------------------------------
  sub recurseErrors {
      my $str;
      my ($value,$space) = @_;
      my $ref = ref $value;
  
      if ($ref eq 'ARRAY') {
          my $i = 0;
          my $isEmpty = 1;
          my @array = @$value;
          $space .= "\t";
          for my $a (@array) {
              if (defined $a) {
                  $isEmpty = 0;
                  $str .= "\n$space$_\[$i\] :";
                  $str .= recurseErrors($a,$space);
              }
              $i++;
          }
          $str .= "= { }" if ($isEmpty);
  
      } elsif ($ref eq 'HASH') {
          $space .= "\t";
          for my $k (sort keys %$value) {
              if ( ( ref($value-&gt;{$k}) eq 'HASH') || (ref $value-&gt;{$k} eq 'ARRAY') ) {
                  my $val = $value-&gt;{$k};
                  $str .= "\n\n$space$k == ";
                  $str .= "$val";
              }
              else {
                  $str .= "\n$space$k == ";
              }
              $str .= recurseErrors($value-&gt;{$k},$space);
        }
  
        # we have reached a scalar (leaf)
      } elsif ($ref eq '') {
          $str .= "$value";
      }
  $str
  }
  #------------------------------------------------------------------
  </code></pre>
  
  <h2>Output:</h2>
  
  <pre>
  arrayofArrays == ARRAY(0x9d9baf8)
  --------------------------------------------
      arrayofArrays[0] :
          arrayofArrays[0] :fred
          arrayofArrays[1] :barney
      arrayofArrays[1] :
          arrayofArrays[0] :george
          arrayofArrays[1] :jane
          arrayofArrays[2] :elroy
      arrayofArrays[2] :
          arrayofArrays[0] :homer
          arrayofArrays[1] :marge
          arrayofArrays[2] :bart
  
  
  arrayofHash == ARRAY(0x9d9bba8)
  --------------------------------------------
      arrayofHash[0] :
          husband == barney
          son == bamm bamm
          wife == betty
      arrayofHash[1] :
          husband == george
          son == elroy
          wife == jane
  
  
  hashofHash == HASH(0x9da45f8)
  --------------------------------------------
  
      flintstones == HASH(0x9d9bb48)
          husband == fred
          pal == barney
  
      jetsons == HASH(0x9d9bbf8)
          his boy == elroy
          husband == george
          wife == jane
  
      simpsons == HASH(0x9d9bc48)
          husband == homer
          kid == bart
          wife == marge
  </pre>