[differences between cumulative patch application and perl5.004]
[p5sagit/p5-mst-13.2.git] / pod / perldsc.pod
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 say just 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 the
45 many different sorts of data structures you might want to develop.  It
46 should also serve as a cookbook of examples.  That way, when you need to
47 create one of these complex data structures, you can just pinch, pilfer, or
48 purloin a drop-in example from here.
49
50 Let's look at each of these possible constructs in detail.  There are separate
51 sections 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 =back
66
67 But for now, let's look at some of the general issues common to all
68 of these types of data structures.
69
70 =head1 REFERENCES
71
72 The most important thing to understand about all data structures in Perl
73 -- including multidimensional arrays--is that even though they might
74 appear otherwise, Perl C<@ARRAY>s and C<%HASH>es are all internally
75 one-dimensional.  They can hold only scalar values (meaning a string,
76 number, or a reference).  They cannot directly contain other arrays or
77 hashes, but instead contain I<references> to other arrays or hashes.
78
79 You can't use a reference to a array or hash in quite the same way that you
80 would a real array or hash.  For C or C++ programmers unused to
81 distinguishing between arrays and pointers to the same, this can be
82 confusing.  If so, just think of it as the difference between a structure
83 and a pointer to a structure.
84
85 You can (and should) read more about references in the perlref(1) man
86 page.  Briefly, references are rather like pointers that know what they
87 point to.  (Objects are also a kind of reference, but we won't be needing
88 them right away--if ever.)  This means that when you have something which
89 looks to you like an access to a two-or-more-dimensional array and/or hash,
90 what's really going on is that the base type is
91 merely a one-dimensional entity that contains references to the next
92 level.  It's just that you can I<use> it as though it were a
93 two-dimensional one.  This is actually the way almost all C
94 multidimensional arrays work as well.
95
96     $list[7][12]                        # array of arrays
97     $list[7]{string}                    # array of hashes
98     $hash{string}[7]                    # hash of arrays
99     $hash{string}{'another string'}     # hash of hashes
100
101 Now, because the top level contains only references, if you try to print
102 out your array in with a simple print() function, you'll get something
103 that doesn't look very nice, like this:
104
105     @LoL = ( [2, 3], [4, 5, 7], [0] );
106     print $LoL[1][2];
107   7
108     print @LoL;
109   ARRAY(0x83c38)ARRAY(0x8b194)ARRAY(0x8b1d0)
110
111
112 That's because Perl doesn't (ever) implicitly dereference your variables.
113 If you want to get at the thing a reference is referring to, then you have
114 to do this yourself using either prefix typing indicators, like
115 C<${$blah}>, C<@{$blah}>, C<@{$blah[$i]}>, or else postfix pointer arrows,
116 like C<$a-E<gt>[3]>, C<$h-E<gt>{fred}>, or even C<$ob-E<gt>method()-E<gt>[3]>.
117
118 =head1 COMMON MISTAKES
119
120 The two most common mistakes made in constructing something like
121 an array of arrays is either accidentally counting the number of
122 elements or else taking a reference to the same memory location
123 repeatedly.  Here's the case where you just get the count instead
124 of a nested array:
125
126     for $i (1..10) {
127         @list = somefunc($i);
128         $LoL[$i] = @list;       # WRONG!
129     }
130
131 That's just the simple case of assigning a list to a scalar and getting
132 its element count.  If that's what you really and truly want, then you
133 might do well to consider being a tad more explicit about it, like this:
134
135     for $i (1..10) {
136         @list = somefunc($i);
137         $counts[$i] = scalar @list;
138     }
139
140 Here's the case of taking a reference to the same memory location
141 again and again:
142
143     for $i (1..10) {
144         @list = somefunc($i);
145         $LoL[$i] = \@list;      # WRONG!
146     }
147
148 So, what's the big problem with that?  It looks right, doesn't it?
149 After all, I just told you that you need an array of references, so by
150 golly, you've made me one!
151
152 Unfortunately, while this is true, it's still broken.  All the references
153 in @LoL refer to the I<very same place>, and they will therefore all hold
154 whatever was last in @list!  It's similar to the problem demonstrated in
155 the following C program:
156
157     #include <pwd.h>
158     main() {
159         struct passwd *getpwnam(), *rp, *dp;
160         rp = getpwnam("root");
161         dp = getpwnam("daemon");
162
163         printf("daemon name is %s\nroot name is %s\n",
164                 dp->pw_name, rp->pw_name);
165     }
166
167 Which will print
168
169     daemon name is daemon
170     root name is daemon
171
172 The problem is that both C<rp> and C<dp> are pointers to the same location
173 in memory!  In C, you'd have to remember to malloc() yourself some new
174 memory.  In Perl, you'll want to use the array constructor C<[]> or the
175 hash constructor C<{}> instead.   Here's the right way to do the preceding
176 broken code fragments:
177
178     for $i (1..10) {
179         @list = somefunc($i);
180         $LoL[$i] = [ @list ];
181     }
182
183 The square brackets make a reference to a new array with a I<copy>
184 of what's in @list at the time of the assignment.  This is what
185 you want.
186
187 Note that this will produce something similar, but it's
188 much harder to read:
189
190     for $i (1..10) {
191         @list = 0 .. $i;
192         @{$LoL[$i]} = @list;
193     }
194
195 Is it the same?  Well, maybe so--and maybe not.  The subtle difference
196 is that when you assign something in square brackets, you know for sure
197 it's always a brand new reference with a new I<copy> of the data.
198 Something else could be going on in this new case with the C<@{$LoL[$i]}}>
199 dereference on the left-hand-side of the assignment.  It all depends on
200 whether C<$LoL[$i]> had been undefined to start with, or whether it
201 already contained a reference.  If you had already populated @LoL with
202 references, as in
203
204     $LoL[3] = \@another_list;
205
206 Then the assignment with the indirection on the left-hand-side would
207 use the existing reference that was already there:
208
209     @{$LoL[3]} = @list;
210
211 Of course, this I<would> have the "interesting" effect of clobbering
212 @another_list.  (Have you ever noticed how when a programmer says
213 something is "interesting", that rather than meaning "intriguing",
214 they're disturbingly more apt to mean that it's "annoying",
215 "difficult", or both?  :-)
216
217 So just remember always to use the array or hash constructors with C<[]>
218 or C<{}>, and you'll be fine, although it's not always optimally
219 efficient.
220
221 Surprisingly, the following dangerous-looking construct will
222 actually work out fine:
223
224     for $i (1..10) {
225         my @list = somefunc($i);
226         $LoL[$i] = \@list;
227     }
228
229 That's because my() is more of a run-time statement than it is a
230 compile-time declaration I<per se>.  This means that the my() variable is
231 remade afresh each time through the loop.  So even though it I<looks> as
232 though you stored the same variable reference each time, you actually did
233 not!  This is a subtle distinction that can produce more efficient code at
234 the risk of misleading all but the most experienced of programmers.  So I
235 usually advise against teaching it to beginners.  In fact, except for
236 passing arguments to functions, I seldom like to see the gimme-a-reference
237 operator (backslash) used much at all in code.  Instead, I advise
238 beginners that they (and most of the rest of us) should try to use the
239 much more easily understood constructors C<[]> and C<{}> instead of
240 relying upon lexical (or dynamic) scoping and hidden reference-counting to
241 do the right thing behind the scenes.
242
243 In summary:
244
245     $LoL[$i] = [ @list ];       # usually best
246     $LoL[$i] = \@list;          # perilous; just how my() was that list?
247     @{ $LoL[$i] } = @list;      # way too tricky for most programmers
248
249
250 =head1 CAVEAT ON PRECEDENCE
251
252 Speaking of things like C<@{$LoL[$i]}>, the following are actually the
253 same thing:
254
255     $listref->[2][2]    # clear
256     $$listref[2][2]     # confusing
257
258 That's because Perl's precedence rules on its five prefix dereferencers
259 (which look like someone swearing: C<$ @ * % &>) make them bind more
260 tightly than the postfix subscripting brackets or braces!  This will no
261 doubt come as a great shock to the C or C++ programmer, who is quite
262 accustomed to using C<*a[i]> to mean what's pointed to by the I<i'th>
263 element of C<a>.  That is, they first take the subscript, and only then
264 dereference the thing at that subscript.  That's fine in C, but this isn't C.
265
266 The seemingly equivalent construct in Perl, C<$$listref[$i]> first does
267 the deref of C<$listref>, making it take $listref as a reference to an
268 array, and then dereference that, and finally tell you the I<i'th> value
269 of the array pointed to by $LoL. If you wanted the C notion, you'd have to
270 write C<${$LoL[$i]}> to force the C<$LoL[$i]> to get evaluated first
271 before the leading C<$> dereferencer.
272
273 =head1 WHY YOU SHOULD ALWAYS C<use strict>
274
275 If this is starting to sound scarier than it's worth, relax.  Perl has
276 some features to help you avoid its most common pitfalls.  The best
277 way to avoid getting confused is to start every program like this:
278
279     #!/usr/bin/perl -w
280     use strict;
281
282 This way, you'll be forced to declare all your variables with my() and
283 also disallow accidental "symbolic dereferencing".  Therefore if you'd done
284 this:
285
286     my $listref = [
287         [ "fred", "barney", "pebbles", "bambam", "dino", ],
288         [ "homer", "bart", "marge", "maggie", ],
289         [ "george", "jane", "elroy", "judy", ],
290     ];
291
292     print $listref[2][2];
293
294 The compiler would immediately flag that as an error I<at compile time>,
295 because you were accidentally accessing C<@listref>, an undeclared
296 variable, and it would thereby remind you to write instead:
297
298     print $listref->[2][2]
299
300 =head1 DEBUGGING
301
302 Before version 5.002, the standard Perl debugger didn't do a very nice job of
303 printing out complex data structures.  With 5.002 or above, the
304 debugger includes several new features, including command line editing as
305 well as the C<x> command to dump out complex data structures.  For
306 example, given the assignment to $LoL above, here's the debugger output:
307
308     DB<1> X $LoL
309     $LoL = ARRAY(0x13b5a0)
310        0  ARRAY(0x1f0a24)
311           0  'fred'
312           1  'barney'
313           2  'pebbles'
314           3  'bambam'
315           4  'dino'
316        1  ARRAY(0x13b558)
317           0  'homer'
318           1  'bart'
319           2  'marge'
320           3  'maggie'
321        2  ARRAY(0x13b540)
322           0  'george'
323           1  'jane'
324           2  'elroy'
325           3  'judy'
326
327 There's also a lowercase B<x> command which is nearly the same.
328
329 =head1 CODE EXAMPLES
330
331 Presented with little comment (these will get their own manpages someday)
332 here are short code examples illustrating access of various
333 types of data structures.
334
335 =head1 LISTS OF LISTS
336
337 =head2 Declaration of a LIST OF LISTS
338
339  @LoL = (
340         [ "fred", "barney" ],
341         [ "george", "jane", "elroy" ],
342         [ "homer", "marge", "bart" ],
343       );
344
345 =head2 Generation of a LIST OF LISTS
346
347  # reading from file
348  while ( <> ) {
349      push @LoL, [ split ];
350  }
351
352  # calling a function
353  for $i ( 1 .. 10 ) {
354      $LoL[$i] = [ somefunc($i) ];
355  }
356
357  # using temp vars
358  for $i ( 1 .. 10 ) {
359      @tmp = somefunc($i);
360      $LoL[$i] = [ @tmp ];
361  }
362
363  # add to an existing row
364  push @{ $LoL[0] }, "wilma", "betty";
365
366 =head2 Access and Printing of a LIST OF LISTS
367
368  # one element
369  $LoL[0][0] = "Fred";
370
371  # another element
372  $LoL[1][1] =~ s/(\w)/\u$1/;
373
374  # print the whole thing with refs
375  for $aref ( @LoL ) {
376      print "\t [ @$aref ],\n";
377  }
378
379  # print the whole thing with indices
380  for $i ( 0 .. $#LoL ) {
381      print "\t [ @{$LoL[$i]} ],\n";
382  }
383
384  # print the whole thing one at a time
385  for $i ( 0 .. $#LoL ) {
386      for $j ( 0 .. $#{ $LoL[$i] } ) {
387          print "elt $i $j is $LoL[$i][$j]\n";
388      }
389  }
390
391 =head1 HASHES OF LISTS
392
393 =head2 Declaration of a HASH OF LISTS
394
395  %HoL = (
396         flintstones        => [ "fred", "barney" ],
397         jetsons            => [ "george", "jane", "elroy" ],
398         simpsons           => [ "homer", "marge", "bart" ],
399       );
400
401 =head2 Generation of a HASH OF LISTS
402
403  # reading from file
404  # flintstones: fred barney wilma dino
405  while ( <> ) {
406      next unless s/^(.*?):\s*//;
407      $HoL{$1} = [ split ];
408  }
409
410  # reading from file; more temps
411  # flintstones: fred barney wilma dino
412  while ( $line = <> ) {
413      ($who, $rest) = split /:\s*/, $line, 2;
414      @fields = split ' ', $rest;
415      $HoL{$who} = [ @fields ];
416  }
417
418  # calling a function that returns a list
419  for $group ( "simpsons", "jetsons", "flintstones" ) {
420      $HoL{$group} = [ get_family($group) ];
421  }
422
423  # likewise, but using temps
424  for $group ( "simpsons", "jetsons", "flintstones" ) {
425      @members = get_family($group);
426      $HoL{$group} = [ @members ];
427  }
428
429  # append new members to an existing family
430  push @{ $HoL{"flintstones"} }, "wilma", "betty";
431
432 =head2 Access and Printing of a HASH OF LISTS
433
434  # one element
435  $HoL{flintstones}[0] = "Fred";
436
437  # another element
438  $HoL{simpsons}[1] =~ s/(\w)/\u$1/;
439
440  # print the whole thing
441  foreach $family ( keys %HoL ) {
442      print "$family: @{ $HoL{$family} }\n"
443  }
444
445  # print the whole thing with indices
446  foreach $family ( keys %HoL ) {
447      print "family: ";
448      foreach $i ( 0 .. $#{ $HoL{$family} } ) {
449          print " $i = $HoL{$family}[$i]";
450      }
451      print "\n";
452  }
453
454  # print the whole thing sorted by number of members
455  foreach $family ( sort { @{$HoL{$b}} <=> @{$HoL{$a}} } keys %HoL ) {
456      print "$family: @{ $HoL{$family} }\n"
457  }
458
459  # print the whole thing sorted by number of members and name
460  foreach $family ( sort {
461                             @{$HoL{$b}} <=> @{$HoL{$a}}
462                                         ||
463                                     $a cmp $b
464             } keys %HoL )
465  {
466      print "$family: ", join(", ", sort @{ $HoL{$family}), "\n";
467  }
468
469 =head1 LISTS OF HASHES
470
471 =head2 Declaration of a LIST OF HASHES
472
473  @LoH = (
474         {
475             Lead     => "fred",
476             Friend   => "barney",
477         },
478         {
479             Lead     => "george",
480             Wife     => "jane",
481             Son      => "elroy",
482         },
483         {
484             Lead     => "homer",
485             Wife     => "marge",
486             Son      => "bart",
487         }
488   );
489
490 =head2 Generation of a LIST OF HASHES
491
492  # reading from file
493  # format: LEAD=fred FRIEND=barney
494  while ( <> ) {
495      $rec = {};
496      for $field ( split ) {
497          ($key, $value) = split /=/, $field;
498          $rec->{$key} = $value;
499      }
500      push @LoH, $rec;
501  }
502
503
504  # reading from file
505  # format: LEAD=fred FRIEND=barney
506  # no temp
507  while ( <> ) {
508      push @LoH, { split /[\s+=]/ };
509  }
510
511  # calling a function  that returns a key,value list, like
512  # "lead","fred","daughter","pebbles"
513  while ( %fields = getnextpairset() ) {
514      push @LoH, { %fields };
515  }
516
517  # likewise, but using no temp vars
518  while (<>) {
519      push @LoH, { parsepairs($_) };
520  }
521
522  # add key/value to an element
523  $LoH[0]{pet} = "dino";
524  $LoH[2]{pet} = "santa's little helper";
525
526 =head2 Access and Printing of a LIST OF HASHES
527
528  # one element
529  $LoH[0]{lead} = "fred";
530
531  # another element
532  $LoH[1]{lead} =~ s/(\w)/\u$1/;
533
534  # print the whole thing with refs
535  for $href ( @LoH ) {
536      print "{ ";
537      for $role ( keys %$href ) {
538          print "$role=$href->{$role} ";
539      }
540      print "}\n";
541  }
542
543  # print the whole thing with indices
544  for $i ( 0 .. $#LoH ) {
545      print "$i is { ";
546      for $role ( keys %{ $LoH[$i] } ) {
547          print "$role=$LoH[$i]{$role} ";
548      }
549      print "}\n";
550  }
551
552  # print the whole thing one at a time
553  for $i ( 0 .. $#LoH ) {
554      for $role ( keys %{ $LoH[$i] } ) {
555          print "elt $i $role is $LoH[$i]{$role}\n";
556      }
557  }
558
559 =head1 HASHES OF HASHES
560
561 =head2 Declaration of a HASH OF HASHES
562
563  %HoH = (
564         flintstones => {
565                 lead      => "fred",
566                 pal       => "barney",
567         },
568         jetsons     => {
569                 lead      => "george",
570                 wife      => "jane",
571                 "his boy" => "elroy",
572         },
573         simpsons    => {
574                 lead      => "homer",
575                 wife      => "marge",
576                 kid       => "bart",
577         },
578  );
579
580 =head2 Generation of a HASH OF HASHES
581
582  # reading from file
583  # flintstones: lead=fred pal=barney wife=wilma pet=dino
584  while ( <> ) {
585      next unless s/^(.*?):\s*//;
586      $who = $1;
587      for $field ( split ) {
588          ($key, $value) = split /=/, $field;
589          $HoH{$who}{$key} = $value;
590      }
591
592
593  # reading from file; more temps
594  while ( <> ) {
595      next unless s/^(.*?):\s*//;
596      $who = $1;
597      $rec = {};
598      $HoH{$who} = $rec;
599      for $field ( split ) {
600          ($key, $value) = split /=/, $field;
601          $rec->{$key} = $value;
602      }
603  }
604
605  # calling a function  that returns a key,value hash
606  for $group ( "simpsons", "jetsons", "flintstones" ) {
607      $HoH{$group} = { get_family($group) };
608  }
609
610  # likewise, but using temps
611  for $group ( "simpsons", "jetsons", "flintstones" ) {
612      %members = get_family($group);
613      $HoH{$group} = { %members };
614  }
615
616  # append new members to an existing family
617  %new_folks = (
618      wife => "wilma",
619      pet  => "dino";
620  );
621
622  for $what (keys %new_folks) {
623      $HoH{flintstones}{$what} = $new_folks{$what};
624  }
625
626 =head2 Access and Printing of a HASH OF HASHES
627
628  # one element
629  $HoH{flintstones}{wife} = "wilma";
630
631  # another element
632  $HoH{simpsons}{lead} =~ s/(\w)/\u$1/;
633
634  # print the whole thing
635  foreach $family ( keys %HoH ) {
636      print "$family: { ";
637      for $role ( keys %{ $HoH{$family} } ) {
638          print "$role=$HoH{$family}{$role} ";
639      }
640      print "}\n";
641  }
642
643  # print the whole thing  somewhat sorted
644  foreach $family ( sort keys %HoH ) {
645      print "$family: { ";
646      for $role ( sort keys %{ $HoH{$family} } ) {
647          print "$role=$HoH{$family}{$role} ";
648      }
649      print "}\n";
650  }
651
652
653  # print the whole thing sorted by number of members
654  foreach $family ( sort { keys %{$HoH{$b}} <=> keys %{$HoH{$a}} } keys %HoH ) {
655      print "$family: { ";
656      for $role ( sort keys %{ $HoH{$family} } ) {
657          print "$role=$HoH{$family}{$role} ";
658      }
659      print "}\n";
660  }
661
662  # establish a sort order (rank) for each role
663  $i = 0;
664  for ( qw(lead wife son daughter pal pet) ) { $rank{$_} = ++$i }
665
666  # now print the whole thing sorted by number of members
667  foreach $family ( sort { keys %{ $HoH{$b} } <=> keys %{ $HoH{$a} } } keys %HoH ) {
668      print "$family: { ";
669      # and print these according to rank order
670      for $role ( sort { $rank{$a} <=> $rank{$b} }  keys %{ $HoH{$family} } ) {
671          print "$role=$HoH{$family}{$role} ";
672      }
673      print "}\n";
674  }
675
676
677 =head1 MORE ELABORATE RECORDS
678
679 =head2 Declaration of MORE ELABORATE RECORDS
680
681 Here's a sample showing how to create and use a record whose fields are of
682 many different sorts:
683
684      $rec = {
685          TEXT      => $string,
686          SEQUENCE  => [ @old_values ],
687          LOOKUP    => { %some_table },
688          THATCODE  => \&some_function,
689          THISCODE  => sub { $_[0] ** $_[1] },
690          HANDLE    => \*STDOUT,
691      };
692
693      print $rec->{TEXT};
694
695      print $rec->{LIST}[0];
696      $last = pop @ { $rec->{SEQUENCE} };
697
698      print $rec->{LOOKUP}{"key"};
699      ($first_k, $first_v) = each %{ $rec->{LOOKUP} };
700
701      $answer = $rec->{THATCODE}->($arg);
702      $answer = $rec->{THISCODE}->($arg1, $arg2);
703
704      # careful of extra block braces on fh ref
705      print { $rec->{HANDLE} } "a string\n";
706
707      use FileHandle;
708      $rec->{HANDLE}->autoflush(1);
709      $rec->{HANDLE}->print(" a string\n");
710
711 =head2 Declaration of a HASH OF COMPLEX RECORDS
712
713      %TV = (
714         flintstones => {
715             series   => "flintstones",
716             nights   => [ qw(monday thursday friday) ],
717             members  => [
718                 { name => "fred",    role => "lead", age  => 36, },
719                 { name => "wilma",   role => "wife", age  => 31, },
720                 { name => "pebbles", role => "kid",  age  =>  4, },
721             ],
722         },
723
724         jetsons     => {
725             series   => "jetsons",
726             nights   => [ qw(wednesday saturday) ],
727             members  => [
728                 { name => "george",  role => "lead", age  => 41, },
729                 { name => "jane",    role => "wife", age  => 39, },
730                 { name => "elroy",   role => "kid",  age  =>  9, },
731             ],
732          },
733
734         simpsons    => {
735             series   => "simpsons",
736             nights   => [ qw(monday) ],
737             members  => [
738                 { name => "homer", role => "lead", age  => 34, },
739                 { name => "marge", role => "wife", age => 37, },
740                 { name => "bart",  role => "kid",  age  =>  11, },
741             ],
742          },
743       );
744
745 =head2 Generation of a HASH OF COMPLEX RECORDS
746
747      # reading from file
748      # this is most easily done by having the file itself be
749      # in the raw data format as shown above.  perl is happy
750      # to parse complex data structures if declared as data, so
751      # sometimes it's easiest to do that
752
753      # here's a piece by piece build up
754      $rec = {};
755      $rec->{series} = "flintstones";
756      $rec->{nights} = [ find_days() ];
757
758      @members = ();
759      # assume this file in field=value syntax
760      while (<>) {
761          %fields = split /[\s=]+/;
762          push @members, { %fields };
763      }
764      $rec->{members} = [ @members ];
765
766      # now remember the whole thing
767      $TV{ $rec->{series} } = $rec;
768
769      ###########################################################
770      # now, you might want to make interesting extra fields that
771      # include pointers back into the same data structure so if
772      # change one piece, it changes everywhere, like for examples
773      # if you wanted a {kids} field that was an array reference
774      # to a list of the kids' records without having duplicate
775      # records and thus update problems.
776      ###########################################################
777      foreach $family (keys %TV) {
778          $rec = $TV{$family}; # temp pointer
779          @kids = ();
780          for $person ( @{ $rec->{members} } ) {
781              if ($person->{role} =~ /kid|son|daughter/) {
782                  push @kids, $person;
783              }
784          }
785          # REMEMBER: $rec and $TV{$family} point to same data!!
786          $rec->{kids} = [ @kids ];
787      }
788
789      # you copied the list, but the list itself contains pointers
790      # to uncopied objects. this means that if you make bart get
791      # older via
792
793      $TV{simpsons}{kids}[0]{age}++;
794
795      # then this would also change in
796      print $TV{simpsons}{members}[2]{age};
797
798      # because $TV{simpsons}{kids}[0] and $TV{simpsons}{members}[2]
799      # both point to the same underlying anonymous hash table
800
801      # print the whole thing
802      foreach $family ( keys %TV ) {
803          print "the $family";
804          print " is on during @{ $TV{$family}{nights} }\n";
805          print "its members are:\n";
806          for $who ( @{ $TV{$family}{members} } ) {
807              print " $who->{name} ($who->{role}), age $who->{age}\n";
808          }
809          print "it turns out that $TV{$family}{lead} has ";
810          print scalar ( @{ $TV{$family}{kids} } ), " kids named ";
811          print join (", ", map { $_->{name} } @{ $TV{$family}{kids} } );
812          print "\n";
813      }
814
815 =head1 Database Ties
816
817 You cannot easily tie a multilevel data structure (such as a hash of
818 hashes) to a dbm file.  The first problem is that all but GDBM and
819 Berkeley DB have size limitations, but beyond that, you also have problems
820 with how references are to be represented on disk.  One experimental
821 module that does partially attempt to address this need is the MLDBM
822 module.  Check your nearest CPAN site as described in L<perlmodlib> for
823 source code to MLDBM.
824
825 =head1 SEE ALSO
826
827 perlref(1), perllol(1), perldata(1), perlobj(1)
828
829 =head1 AUTHOR
830
831 Tom Christiansen <F<tchrist@perl.com>>
832
833 Last update:
834 Wed Oct 23 04:57:50 MET DST 1996