[inseparable changes from patch from perl-5.003_97d to perl-5.003_97e]
[p5sagit/p5-mst-13.2.git] / pod / perldsc.pod
CommitLineData
cb1a09d0 1=head1 NAME
4633a7c4 2
cb1a09d0 3perldsc - Perl Data Structures Cookbook
4633a7c4 4
cb1a09d0 5=head1 DESCRIPTION
4633a7c4 6
7The single feature most sorely lacking in the Perl programming language
8prior to its 5.0 release was complex data structures. Even without direct
9language support, some valiant programmers did manage to emulate them, but
10it was hard work and not for the faint of heart. You could occasionally
11get away with the C<$m{$LoL,$b}> notation borrowed from I<awk> in which the
12keys are actually more like a single concatenated string C<"$LoL$b">, but
13traversal and sorting were difficult. More desperate programmers even
14hacked Perl's internal symbol table directly, a strategy that proved hard
15to develop and maintain--to put it mildly.
16
17The 5.0 release of Perl let us have complex data structures. You
18may now write something like this and all of a sudden, you'd have a array
19with three dimensions!
20
21 for $x (1 .. 10) {
22 for $y (1 .. 10) {
23 for $z (1 .. 10) {
4973169d 24 $LoL[$x][$y][$z] =
4633a7c4 25 $x ** $y + $z;
26 }
27 }
28 }
29
30Alas, however simple this may appear, underneath it's a much more
31elaborate construct than meets the eye!
32
5f05dabc 33How do you print it out? Why can't you say just C<print @LoL>? How do
4633a7c4 34you sort it? How can you pass it to a function or get one of these back
35from a function? Is is an object? Can you save it to disk to read
36back later? How do you access whole rows or columns of that matrix? Do
4973169d 37all the values have to be numeric?
4633a7c4 38
39As you see, it's quite easy to become confused. While some small portion
40of the blame for this can be attributed to the reference-based
41implementation, it's really more due to a lack of existing documentation with
42examples designed for the beginner.
43
5f05dabc 44This document is meant to be a detailed but understandable treatment of the
45many different sorts of data structures you might want to develop. It
46should also serve as a cookbook of examples. That way, when you need to
47create one of these complex data structures, you can just pinch, pilfer, or
48purloin a drop-in example from here.
4633a7c4 49
50Let's look at each of these possible constructs in detail. There are separate
28757baa 51sections on each of the following:
4633a7c4 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
4633a7c4 65=back
66
67But for now, let's look at some of the general issues common to all
4973169d 68of these types of data structures.
4633a7c4 69
70=head1 REFERENCES
71
72The most important thing to understand about all data structures in Perl
73-- including multidimensional arrays--is that even though they might
74appear otherwise, Perl C<@ARRAY>s and C<%HASH>es are all internally
5f05dabc 75one-dimensional. They can hold only scalar values (meaning a string,
4633a7c4 76number, or a reference). They cannot directly contain other arrays or
77hashes, but instead contain I<references> to other arrays or hashes.
78
5f05dabc 79You can't use a reference to a array or hash in quite the same way that you
80would a real array or hash. For C or C++ programmers unused to
81distinguishing between arrays and pointers to the same, this can be
82confusing. If so, just think of it as the difference between a structure
83and a pointer to a structure.
4633a7c4 84
85You can (and should) read more about references in the perlref(1) man
86page. Briefly, references are rather like pointers that know what they
87point to. (Objects are also a kind of reference, but we won't be needing
4973169d 88them right away--if ever.) This means that when you have something which
89looks to you like an access to a two-or-more-dimensional array and/or hash,
90what's really going on is that the base type is
4633a7c4 91merely a one-dimensional entity that contains references to the next
92level. It's just that you can I<use> it as though it were a
93two-dimensional one. This is actually the way almost all C
94multidimensional 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
5f05dabc 101Now, because the top level contains only references, if you try to print
4633a7c4 102out your array in with a simple print() function, you'll get something
103that 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
112That's because Perl doesn't (ever) implicitly dereference your variables.
113If you want to get at the thing a reference is referring to, then you have
114to do this yourself using either prefix typing indicators, like
115C<${$blah}>, C<@{$blah}>, C<@{$blah[$i]}>, or else postfix pointer arrows,
116like 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
120The two most common mistakes made in constructing something like
121an array of arrays is either accidentally counting the number of
122elements or else taking a reference to the same memory location
123repeatedly. Here's the case where you just get the count instead
124of a nested array:
125
126 for $i (1..10) {
127 @list = somefunc($i);
128 $LoL[$i] = @list; # WRONG!
4973169d 129 }
4633a7c4 130
131That's just the simple case of assigning a list to a scalar and getting
132its element count. If that's what you really and truly want, then you
133might do well to consider being a tad more explicit about it, like this:
134
135 for $i (1..10) {
136 @list = somefunc($i);
54310121 137 $counts[$i] = scalar @list;
4973169d 138 }
4633a7c4 139
140Here's the case of taking a reference to the same memory location
141again and again:
142
143 for $i (1..10) {
144 @list = somefunc($i);
145 $LoL[$i] = \@list; # WRONG!
4973169d 146 }
4633a7c4 147
5f05dabc 148So, what's the big problem with that? It looks right, doesn't it?
4633a7c4 149After all, I just told you that you need an array of references, so by
150golly, you've made me one!
151
152Unfortunately, while this is true, it's still broken. All the references
153in @LoL refer to the I<very same place>, and they will therefore all hold
154whatever was last in @list! It's similar to the problem demonstrated in
155the 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
4973169d 163 printf("daemon name is %s\nroot name is %s\n",
4633a7c4 164 dp->pw_name, rp->pw_name);
165 }
166
167Which will print
168
169 daemon name is daemon
4973169d 170 root name is daemon
4633a7c4 171
172The problem is that both C<rp> and C<dp> are pointers to the same location
173in memory! In C, you'd have to remember to malloc() yourself some new
174memory. In Perl, you'll want to use the array constructor C<[]> or the
175hash constructor C<{}> instead. Here's the right way to do the preceding
4973169d 176broken code fragments:
4633a7c4 177
178 for $i (1..10) {
179 @list = somefunc($i);
180 $LoL[$i] = [ @list ];
4973169d 181 }
4633a7c4 182
183The square brackets make a reference to a new array with a I<copy>
184of what's in @list at the time of the assignment. This is what
4973169d 185you want.
4633a7c4 186
187Note that this will produce something similar, but it's
188much harder to read:
189
190 for $i (1..10) {
191 @list = 0 .. $i;
192 @{$LoL[$i]} = @list;
4973169d 193 }
4633a7c4 194
195Is it the same? Well, maybe so--and maybe not. The subtle difference
196is that when you assign something in square brackets, you know for sure
197it's always a brand new reference with a new I<copy> of the data.
198Something else could be going on in this new case with the C<@{$LoL[$i]}}>
199dereference on the left-hand-side of the assignment. It all depends on
200whether C<$LoL[$i]> had been undefined to start with, or whether it
201already contained a reference. If you had already populated @LoL with
202references, as in
203
204 $LoL[3] = \@another_list;
205
206Then the assignment with the indirection on the left-hand-side would
207use the existing reference that was already there:
208
209 @{$LoL[3]} = @list;
210
211Of course, this I<would> have the "interesting" effect of clobbering
212@another_list. (Have you ever noticed how when a programmer says
213something is "interesting", that rather than meaning "intriguing",
214they're disturbingly more apt to mean that it's "annoying",
215"difficult", or both? :-)
216
5f05dabc 217So just remember always to use the array or hash constructors with C<[]>
4633a7c4 218or C<{}>, and you'll be fine, although it's not always optimally
4973169d 219efficient.
4633a7c4 220
221Surprisingly, the following dangerous-looking construct will
222actually work out fine:
223
224 for $i (1..10) {
225 my @list = somefunc($i);
226 $LoL[$i] = \@list;
4973169d 227 }
4633a7c4 228
229That's because my() is more of a run-time statement than it is a
230compile-time declaration I<per se>. This means that the my() variable is
231remade afresh each time through the loop. So even though it I<looks> as
232though you stored the same variable reference each time, you actually did
233not! This is a subtle distinction that can produce more efficient code at
234the risk of misleading all but the most experienced of programmers. So I
235usually advise against teaching it to beginners. In fact, except for
236passing arguments to functions, I seldom like to see the gimme-a-reference
237operator (backslash) used much at all in code. Instead, I advise
238beginners that they (and most of the rest of us) should try to use the
239much more easily understood constructors C<[]> and C<{}> instead of
240relying upon lexical (or dynamic) scoping and hidden reference-counting to
241do the right thing behind the scenes.
242
243In 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
4973169d 250=head1 CAVEAT ON PRECEDENCE
4633a7c4 251
252Speaking of things like C<@{$LoL[$i]}>, the following are actually the
253same thing:
254
255 $listref->[2][2] # clear
256 $$listref[2][2] # confusing
257
258That's because Perl's precedence rules on its five prefix dereferencers
259(which look like someone swearing: C<$ @ * % &>) make them bind more
260tightly than the postfix subscripting brackets or braces! This will no
261doubt come as a great shock to the C or C++ programmer, who is quite
262accustomed to using C<*a[i]> to mean what's pointed to by the I<i'th>
263element of C<a>. That is, they first take the subscript, and only then
264dereference the thing at that subscript. That's fine in C, but this isn't C.
265
266The seemingly equivalent construct in Perl, C<$$listref[$i]> first does
267the deref of C<$listref>, making it take $listref as a reference to an
268array, and then dereference that, and finally tell you the I<i'th> value
269of the array pointed to by $LoL. If you wanted the C notion, you'd have to
270write C<${$LoL[$i]}> to force the C<$LoL[$i]> to get evaluated first
271before the leading C<$> dereferencer.
272
273=head1 WHY YOU SHOULD ALWAYS C<use strict>
274
275If this is starting to sound scarier than it's worth, relax. Perl has
276some features to help you avoid its most common pitfalls. The best
277way to avoid getting confused is to start every program like this:
278
279 #!/usr/bin/perl -w
280 use strict;
281
282This way, you'll be forced to declare all your variables with my() and
283also disallow accidental "symbolic dereferencing". Therefore if you'd done
284this:
285
286 my $listref = [
287 [ "fred", "barney", "pebbles", "bambam", "dino", ],
288 [ "homer", "bart", "marge", "maggie", ],
5f05dabc 289 [ "george", "jane", "elroy", "judy", ],
4633a7c4 290 ];
291
292 print $listref[2][2];
293
294The compiler would immediately flag that as an error I<at compile time>,
295because you were accidentally accessing C<@listref>, an undeclared
5f05dabc 296variable, and it would thereby remind you to write instead:
4633a7c4 297
298 print $listref->[2][2]
299
300=head1 DEBUGGING
301
a6006777 302Before version 5.002, the standard Perl debugger didn't do a very nice job of
303printing out complex data structures. With 5.002 or above, the
4973169d 304debugger includes several new features, including command line editing as
305well as the C<x> command to dump out complex data structures. For
306example, given the assignment to $LoL above, here's the debugger output:
4633a7c4 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'
5f05dabc 324 2 'elroy'
4633a7c4 325 3 'judy'
326
68dc0745 327There's also a lowercase B<x> command which is nearly the same.
4633a7c4 328
cb1a09d0 329=head1 CODE EXAMPLES
330
54310121 331Presented with little comment (these will get their own manpages someday)
4973169d 332here are short code examples illustrating access of various
cb1a09d0 333types 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 ];
4973169d 350 }
cb1a09d0 351
352 # calling a function
353 for $i ( 1 .. 10 ) {
354 $LoL[$i] = [ somefunc($i) ];
4973169d 355 }
cb1a09d0 356
357 # using temp vars
358 for $i ( 1 .. 10 ) {
359 @tmp = somefunc($i);
360 $LoL[$i] = [ @tmp ];
4973169d 361 }
cb1a09d0 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";
4973169d 377 }
cb1a09d0 378
379 # print the whole thing with indices
380 for $i ( 0 .. $#LoL ) {
381 print "\t [ @{$LoL[$i]} ],\n";
4973169d 382 }
cb1a09d0 383
384 # print the whole thing one at a time
385 for $i ( 0 .. $#LoL ) {
28757baa 386 for $j ( 0 .. $#{ $LoL[$i] } ) {
cb1a09d0 387 print "elt $i $j is $LoL[$i][$j]\n";
388 }
4973169d 389 }
cb1a09d0 390
391=head1 HASHES OF LISTS
392
393=head2 Declaration of a HASH OF LISTS
394
395 %HoL = (
28757baa 396 flintstones => [ "fred", "barney" ],
397 jetsons => [ "george", "jane", "elroy" ],
398 simpsons => [ "homer", "marge", "bart" ],
cb1a09d0 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 ];
4973169d 408 }
cb1a09d0 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 ];
4973169d 416 }
cb1a09d0 417
418 # calling a function that returns a list
419 for $group ( "simpsons", "jetsons", "flintstones" ) {
420 $HoL{$group} = [ get_family($group) ];
4973169d 421 }
cb1a09d0 422
423 # likewise, but using temps
424 for $group ( "simpsons", "jetsons", "flintstones" ) {
425 @members = get_family($group);
426 $HoL{$group} = [ @members ];
4973169d 427 }
cb1a09d0 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"
4973169d 443 }
cb1a09d0 444
445 # print the whole thing with indices
446 foreach $family ( keys %HoL ) {
447 print "family: ";
5f05dabc 448 foreach $i ( 0 .. $#{ $HoL{$family} } ) {
cb1a09d0 449 print " $i = $HoL{$family}[$i]";
450 }
451 print "\n";
4973169d 452 }
cb1a09d0 453
454 # print the whole thing sorted by number of members
28757baa 455 foreach $family ( sort { @{$HoL{$b}} <=> @{$HoL{$a}} } keys %HoL ) {
cb1a09d0 456 print "$family: @{ $HoL{$family} }\n"
4973169d 457 }
cb1a09d0 458
459 # print the whole thing sorted by number of members and name
54310121 460 foreach $family ( sort {
28757baa 461 @{$HoL{$b}} <=> @{$HoL{$a}}
462 ||
463 $a cmp $b
464 } keys %HoL )
465 {
cb1a09d0 466 print "$family: ", join(", ", sort @{ $HoL{$family}), "\n";
4973169d 467 }
cb1a09d0 468
469=head1 LISTS OF HASHES
470
471=head2 Declaration of a LIST OF HASHES
472
473 @LoH = (
474 {
4973169d 475 Lead => "fred",
476 Friend => "barney",
cb1a09d0 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;
4973169d 501 }
cb1a09d0 502
503
504 # reading from file
505 # format: LEAD=fred FRIEND=barney
506 # no temp
507 while ( <> ) {
508 push @LoH, { split /[\s+=]/ };
4973169d 509 }
cb1a09d0 510
511 # calling a function that returns a key,value list, like
512 # "lead","fred","daughter","pebbles"
1fef88e7 513 while ( %fields = getnextpairset() ) {
cb1a09d0 514 push @LoH, { %fields };
4973169d 515 }
cb1a09d0 516
517 # likewise, but using no temp vars
518 while (<>) {
519 push @LoH, { parsepairs($_) };
4973169d 520 }
cb1a09d0 521
522 # add key/value to an element
4973169d 523 $LoH[0]{pet} = "dino";
524 $LoH[2]{pet} = "santa's little helper";
cb1a09d0 525
526=head2 Access and Printing of a LIST OF HASHES
527
528 # one element
4973169d 529 $LoH[0]{lead} = "fred";
cb1a09d0 530
531 # another element
4973169d 532 $LoH[1]{lead} =~ s/(\w)/\u$1/;
cb1a09d0 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";
4973169d 541 }
cb1a09d0 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";
4973169d 550 }
cb1a09d0 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 }
4973169d 557 }
cb1a09d0 558
559=head1 HASHES OF HASHES
560
561=head2 Declaration of a HASH OF HASHES
562
563 %HoH = (
28757baa 564 flintstones => {
565 lead => "fred",
566 pal => "barney",
cb1a09d0 567 },
28757baa 568 jetsons => {
569 lead => "george",
570 wife => "jane",
571 "his boy" => "elroy",
4973169d 572 },
28757baa 573 simpsons => {
574 lead => "homer",
575 wife => "marge",
576 kid => "bart",
4973169d 577 },
578 );
cb1a09d0 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 }
4973169d 603 }
cb1a09d0 604
cb1a09d0 605 # calling a function that returns a key,value hash
606 for $group ( "simpsons", "jetsons", "flintstones" ) {
607 $HoH{$group} = { get_family($group) };
4973169d 608 }
cb1a09d0 609
610 # likewise, but using temps
611 for $group ( "simpsons", "jetsons", "flintstones" ) {
612 %members = get_family($group);
613 $HoH{$group} = { %members };
4973169d 614 }
cb1a09d0 615
616 # append new members to an existing family
617 %new_folks = (
28757baa 618 wife => "wilma",
619 pet => "dino";
cb1a09d0 620 );
4973169d 621
cb1a09d0 622 for $what (keys %new_folks) {
623 $HoH{flintstones}{$what} = $new_folks{$what};
4973169d 624 }
cb1a09d0 625
626=head2 Access and Printing of a HASH OF HASHES
627
628 # one element
4973169d 629 $HoH{flintstones}{wife} = "wilma";
cb1a09d0 630
631 # another element
632 $HoH{simpsons}{lead} =~ s/(\w)/\u$1/;
633
634 # print the whole thing
635 foreach $family ( keys %HoH ) {
1fef88e7 636 print "$family: { ";
4973169d 637 for $role ( keys %{ $HoH{$family} } ) {
cb1a09d0 638 print "$role=$HoH{$family}{$role} ";
639 }
640 print "}\n";
4973169d 641 }
cb1a09d0 642
643 # print the whole thing somewhat sorted
644 foreach $family ( sort keys %HoH ) {
1fef88e7 645 print "$family: { ";
4973169d 646 for $role ( sort keys %{ $HoH{$family} } ) {
cb1a09d0 647 print "$role=$HoH{$family}{$role} ";
648 }
649 print "}\n";
4973169d 650 }
cb1a09d0 651
652
653 # print the whole thing sorted by number of members
28757baa 654 foreach $family ( sort { keys %{$HoH{$b}} <=> keys %{$HoH{$a}} } keys %HoH ) {
1fef88e7 655 print "$family: { ";
4973169d 656 for $role ( sort keys %{ $HoH{$family} } ) {
cb1a09d0 657 print "$role=$HoH{$family}{$role} ";
658 }
659 print "}\n";
4973169d 660 }
cb1a09d0 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
28757baa 667 foreach $family ( sort { keys %{ $HoH{$b} } <=> keys %{ $HoH{$a} } } keys %HoH ) {
1fef88e7 668 print "$family: { ";
cb1a09d0 669 # and print these according to rank order
28757baa 670 for $role ( sort { $rank{$a} <=> $rank{$b} } keys %{ $HoH{$family} } ) {
cb1a09d0 671 print "$role=$HoH{$family}{$role} ";
672 }
673 print "}\n";
4973169d 674 }
cb1a09d0 675
676
677=head1 MORE ELABORATE RECORDS
678
679=head2 Declaration of MORE ELABORATE RECORDS
680
681Here's a sample showing how to create and use a record whose fields are of
682many different sorts:
683
684 $rec = {
4973169d 685 TEXT => $string,
686 SEQUENCE => [ @old_values ],
687 LOOKUP => { %some_table },
688 THATCODE => \&some_function,
689 THISCODE => sub { $_[0] ** $_[1] },
690 HANDLE => \*STDOUT,
cb1a09d0 691 };
692
4973169d 693 print $rec->{TEXT};
cb1a09d0 694
695 print $rec->{LIST}[0];
4973169d 696 $last = pop @ { $rec->{SEQUENCE} };
cb1a09d0 697
698 print $rec->{LOOKUP}{"key"};
699 ($first_k, $first_v) = each %{ $rec->{LOOKUP} };
700
4973169d 701 $answer = &{ $rec->{THATCODE} }($arg);
702 $answer = &{ $rec->{THISCODE} }($arg1, $arg2);
cb1a09d0 703
704 # careful of extra block braces on fh ref
4973169d 705 print { $rec->{HANDLE} } "a string\n";
cb1a09d0 706
707 use FileHandle;
4973169d 708 $rec->{HANDLE}->autoflush(1);
709 $rec->{HANDLE}->print(" a string\n");
cb1a09d0 710
711=head2 Declaration of a HASH OF COMPLEX RECORDS
712
713 %TV = (
28757baa 714 flintstones => {
cb1a09d0 715 series => "flintstones",
4973169d 716 nights => [ qw(monday thursday friday) ],
cb1a09d0 717 members => [
718 { name => "fred", role => "lead", age => 36, },
719 { name => "wilma", role => "wife", age => 31, },
4973169d 720 { name => "pebbles", role => "kid", age => 4, },
cb1a09d0 721 ],
722 },
723
28757baa 724 jetsons => {
cb1a09d0 725 series => "jetsons",
4973169d 726 nights => [ qw(wednesday saturday) ],
cb1a09d0 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
28757baa 734 simpsons => {
cb1a09d0 735 series => "simpsons",
4973169d 736 nights => [ qw(monday) ],
cb1a09d0 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
5f05dabc 750 # to parse complex data structures if declared as data, so
cb1a09d0 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
1fef88e7 760 while (<>) {
cb1a09d0 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 = ();
28757baa 780 for $person ( @{ $rec->{members} } ) {
cb1a09d0 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 }
28757baa 809 print "it turns out that $TV{$family}{lead} has ";
cb1a09d0 810 print scalar ( @{ $TV{$family}{kids} } ), " kids named ";
811 print join (", ", map { $_->{name} } @{ $TV{$family}{kids} } );
812 print "\n";
813 }
814
c07a80fd 815=head1 Database Ties
816
817You cannot easily tie a multilevel data structure (such as a hash of
818hashes) to a dbm file. The first problem is that all but GDBM and
819Berkeley DB have size limitations, but beyond that, you also have problems
820with how references are to be represented on disk. One experimental
5f05dabc 821module that does partially attempt to address this need is the MLDBM
c07a80fd 822module. Check your nearest CPAN site as described in L<perlmod> for
823source code to MLDBM.
824
4633a7c4 825=head1 SEE ALSO
826
1fef88e7 827perlref(1), perllol(1), perldata(1), perlobj(1)
4633a7c4 828
829=head1 AUTHOR
830
9607fc9c 831Tom Christiansen <F<tchrist@perl.com>>
4633a7c4 832
4973169d 833Last update:
28757baa 834Wed Oct 23 04:57:50 MET DST 1996