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