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