home *** CD-ROM | disk | FTP | other *** search
/ BURKS 2 / BURKS_AUG97.ISO / SLAKWARE / D13 / PERL2.TGZ / perl2.tar / usr / lib / perl5 / pod / perldsc.pod < prev    next >
Text File  |  1996-06-28  |  25KB  |  838 lines

  1. =head1 NAME
  2.  
  3. perldsc - Perl Data Structures Cookbook
  4.  
  5. =head1 DESCRIPTION
  6.  
  7. The single feature most sorely lacking in the Perl programming language
  8. prior to its 5.0 release was complex data structures.  Even without direct
  9. language support, some valiant programmers did manage to emulate them, but
  10. it was hard work and not for the faint of heart.  You could occasionally
  11. get away with the C<$m{$LoL,$b}> notation borrowed from I<awk> in which the
  12. keys are actually more like a single concatenated string C<"$LoL$b">, but
  13. traversal and sorting were difficult.  More desperate programmers even
  14. hacked Perl's internal symbol table directly, a strategy that proved hard
  15. to develop and maintain--to put it mildly.
  16.  
  17. The 5.0 release of Perl let us have complex data structures.  You
  18. may now write something like this and all of a sudden, you'd have a array
  19. with three dimensions!
  20.  
  21.     for $x (1 .. 10) {
  22.     for $y (1 .. 10) {
  23.         for $z (1 .. 10) {
  24.         $LoL[$x][$y][$z] = 
  25.             $x ** $y + $z;
  26.         }
  27.     }
  28.     }
  29.  
  30. Alas, however simple this may appear, underneath it's a much more
  31. elaborate construct than meets the eye!
  32.  
  33. How do you print it out?  Why can't you just say C<print @LoL>?  How do
  34. you sort it?  How can you pass it to a function or get one of these back
  35. from a function?  Is is an object?  Can you save it to disk to read
  36. back later?  How do you access whole rows or columns of that matrix?  Do
  37. all the values have to be numeric?  
  38.  
  39. As you see, it's quite easy to become confused.  While some small portion
  40. of the blame for this can be attributed to the reference-based
  41. implementation, it's really more due to a lack of existing documentation with
  42. examples designed for the beginner.
  43.  
  44. This document is meant to be a detailed but understandable treatment of
  45. the many different sorts of data structures you might want to develop.  It should
  46. also serve as a cookbook of examples.  That way, when you need to create one of these
  47. complex data structures, you can just pinch, pilfer, or purloin
  48. a drop-in example from here.
  49.  
  50. Let's look at each of these possible constructs in detail.  There are separate
  51. documents on each of the following:
  52.  
  53. =over 5
  54.  
  55. =item * arrays of arrays
  56.  
  57. =item * hashes of arrays
  58.  
  59. =item * arrays of hashes
  60.  
  61. =item * hashes of hashes
  62.  
  63. =item * more elaborate constructs
  64.  
  65. =item * recursive and self-referential data structures
  66.  
  67. =item * objects
  68.  
  69. =back
  70.  
  71. But for now, let's look at some of the general issues common to all
  72. of these types of data structures. 
  73.  
  74. =head1 REFERENCES
  75.  
  76. The most important thing to understand about all data structures in Perl
  77. -- including multidimensional arrays--is that even though they might
  78. appear otherwise, Perl C<@ARRAY>s and C<%HASH>es are all internally
  79. one-dimensional.  They can only hold scalar values (meaning a string,
  80. number, or a reference).  They cannot directly contain other arrays or
  81. hashes, but instead contain I<references> to other arrays or hashes.
  82.  
  83. You can't use a reference to a array or hash in quite the same way that
  84. you would a real array or hash.  For C or C++ programmers unused to distinguishing
  85. between arrays and pointers to the same, this can be confusing.  If so,
  86. just think of it as the difference between a structure and a pointer to a
  87. structure.  
  88.  
  89. You can (and should) read more about references in the perlref(1) man
  90. page.  Briefly, references are rather like pointers that know what they
  91. point to.  (Objects are also a kind of reference, but we won't be needing
  92. them right away--if ever.)  That means that when you have something that
  93. looks to you like an access to two-or-more-dimensional array and/or hash,
  94. that what's really going on is that in all these cases, the base type is
  95. merely a one-dimensional entity that contains references to the next
  96. level.  It's just that you can I<use> it as though it were a
  97. two-dimensional one.  This is actually the way almost all C
  98. multidimensional arrays work as well.
  99.  
  100.     $list[7][12]            # array of arrays
  101.     $list[7]{string}            # array of hashes
  102.     $hash{string}[7]            # hash of arrays
  103.     $hash{string}{'another string'}    # hash of hashes
  104.  
  105. Now, because the top level only contains references, if you try to print
  106. out your array in with a simple print() function, you'll get something
  107. that doesn't look very nice, like this:
  108.  
  109.     @LoL = ( [2, 3], [4, 5, 7], [0] );
  110.     print $LoL[1][2];
  111.   7
  112.     print @LoL;
  113.   ARRAY(0x83c38)ARRAY(0x8b194)ARRAY(0x8b1d0)
  114.  
  115.  
  116. That's because Perl doesn't (ever) implicitly dereference your variables.
  117. If you want to get at the thing a reference is referring to, then you have
  118. to do this yourself using either prefix typing indicators, like
  119. C<${$blah}>, C<@{$blah}>, C<@{$blah[$i]}>, or else postfix pointer arrows,
  120. like C<$a-E<gt>[3]>, C<$h-E<gt>{fred}>, or even C<$ob-E<gt>method()-E<gt>[3]>.
  121.  
  122. =head1 COMMON MISTAKES
  123.  
  124. The two most common mistakes made in constructing something like
  125. an array of arrays is either accidentally counting the number of
  126. elements or else taking a reference to the same memory location
  127. repeatedly.  Here's the case where you just get the count instead
  128. of a nested array:
  129.  
  130.     for $i (1..10) {
  131.     @list = somefunc($i);
  132.     $LoL[$i] = @list;    # WRONG!
  133.     } 
  134.  
  135. That's just the simple case of assigning a list to a scalar and getting
  136. its element count.  If that's what you really and truly want, then you
  137. might do well to consider being a tad more explicit about it, like this:
  138.  
  139.     for $i (1..10) {
  140.     @list = somefunc($i);
  141.     $counts[$i] = scalar @list;    
  142.     } 
  143.  
  144. Here's the case of taking a reference to the same memory location
  145. again and again:
  146.  
  147.     for $i (1..10) {
  148.     @list = somefunc($i);
  149.     $LoL[$i] = \@list;    # WRONG!
  150.     } 
  151.  
  152. So, just what's the big problem with that?  It looks right, doesn't it?
  153. After all, I just told you that you need an array of references, so by
  154. golly, you've made me one!
  155.  
  156. Unfortunately, while this is true, it's still broken.  All the references
  157. in @LoL refer to the I<very same place>, and they will therefore all hold
  158. whatever was last in @list!  It's similar to the problem demonstrated in
  159. the following C program:
  160.  
  161.     #include <pwd.h>
  162.     main() {
  163.     struct passwd *getpwnam(), *rp, *dp;
  164.     rp = getpwnam("root");
  165.     dp = getpwnam("daemon");
  166.  
  167.     printf("daemon name is %s\nroot name is %s\n", 
  168.         dp->pw_name, rp->pw_name);
  169.     }
  170.  
  171. Which will print
  172.  
  173.     daemon name is daemon
  174.     root name is daemon 
  175.  
  176. The problem is that both C<rp> and C<dp> are pointers to the same location
  177. in memory!  In C, you'd have to remember to malloc() yourself some new
  178. memory.  In Perl, you'll want to use the array constructor C<[]> or the
  179. hash constructor C<{}> instead.   Here's the right way to do the preceding
  180. broken code fragments
  181.  
  182.     for $i (1..10) {
  183.     @list = somefunc($i);
  184.     $LoL[$i] = [ @list ];
  185.     } 
  186.  
  187. The square brackets make a reference to a new array with a I<copy>
  188. of what's in @list at the time of the assignment.  This is what
  189. you want.  
  190.  
  191. Note that this will produce something similar, but it's
  192. much harder to read:
  193.  
  194.     for $i (1..10) {
  195.     @list = 0 .. $i;
  196.     @{$LoL[$i]} = @list;
  197.     } 
  198.  
  199. Is it the same?  Well, maybe so--and maybe not.  The subtle difference
  200. is that when you assign something in square brackets, you know for sure
  201. it's always a brand new reference with a new I<copy> of the data.
  202. Something else could be going on in this new case with the C<@{$LoL[$i]}}>
  203. dereference on the left-hand-side of the assignment.  It all depends on
  204. whether C<$LoL[$i]> had been undefined to start with, or whether it
  205. already contained a reference.  If you had already populated @LoL with
  206. references, as in
  207.  
  208.     $LoL[3] = \@another_list;
  209.  
  210. Then the assignment with the indirection on the left-hand-side would
  211. use the existing reference that was already there:
  212.  
  213.     @{$LoL[3]} = @list;
  214.  
  215. Of course, this I<would> have the "interesting" effect of clobbering
  216. @another_list.  (Have you ever noticed how when a programmer says
  217. something is "interesting", that rather than meaning "intriguing",
  218. they're disturbingly more apt to mean that it's "annoying",
  219. "difficult", or both?  :-)
  220.  
  221. So just remember to always use the array or hash constructors with C<[]>
  222. or C<{}>, and you'll be fine, although it's not always optimally
  223. efficient.  
  224.  
  225. Surprisingly, the following dangerous-looking construct will
  226. actually work out fine:
  227.  
  228.     for $