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