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