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<< $arr->[3] >>, C<< $hash->{fred} >>, or even C<< $obj->method()->[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 # same, but using a hash slice 656 @{ $HoH{flintstones} }{ keys %new_folks } = values %new_folks; 657 658 # same, but without a %new_folks variable 659 @{ $HoH{flintstones} }{ "wife", "pet" } = ( "wilma", "dino" ); 660 661=head2 Access and Printing of a HASH OF HASHES 662 663 # one element 664 $HoH{flintstones}{wife} = "wilma"; 665 666 # another element 667 $HoH{simpsons}{lead} =~ s/(\w)/\u$1/; 668 669 # print the whole thing 670 foreach my $family ( keys %HoH ) { 671 print "$family: { "; 672 for my $role ( keys $HoH{$family}->%* ) { 673 print "$role=$HoH{$family}{$role} "; 674 } 675 print "}\n"; 676 } 677 678 # print the whole thing somewhat sorted 679 foreach my $family ( sort keys %HoH ) { 680 print "$family: { "; 681 for my $role ( sort keys $HoH{$family}->%* ) { 682 print "$role=$HoH{$family}{$role} "; 683 } 684 print "}\n"; 685 } 686 687 688 # print the whole thing sorted by number of members 689 foreach my $family ( sort { $HoH{$b}->%* <=> $HoH{$a}->%* } keys %HoH ) { 690 print "$family: { "; 691 for my $role ( sort keys $HoH{$family}->%* ) { 692 print "$role=$HoH{$family}{$role} "; 693 } 694 print "}\n"; 695 } 696 697 # establish a sort order (rank) for each role 698 my $i = 0; 699 my %rank; 700 for ( qw(lead wife son daughter pal pet) ) { $rank{$_} = ++$i } 701 702 # now print the whole thing sorted by number of members 703 foreach my $family ( sort { $HoH{$b}->%* <=> $HoH{$a}->%* } keys %HoH ) { 704 print "$family: { "; 705 # and print these according to rank order 706 for my $role ( sort { $rank{$a} <=> $rank{$b} } 707 keys $HoH{$family}->%* ) 708 { 709 print "$role=$HoH{$family}{$role} "; 710 } 711 print "}\n"; 712 } 713 714 715=head1 MORE ELABORATE RECORDS 716X<record> X<structure> X<struct> 717 718=head2 Declaration of MORE ELABORATE RECORDS 719 720Here's a sample showing how to create and use a record whose fields are of 721many different sorts: 722 723 my $rec = { 724 TEXT => $string, 725 SEQUENCE => [ @old_values ], 726 LOOKUP => { %some_table }, 727 THATCODE => \&some_function, 728 THISCODE => sub { $_[0] ** $_[1] }, 729 HANDLE => \*STDOUT, 730 }; 731 732 print $rec->{TEXT}; 733 734 print $rec->{SEQUENCE}[0]; 735 my $last = pop $rec->{SEQUENCE}->@*; 736 737 print $rec->{LOOKUP}{"key"}; 738 my ($first_k, $first_v) = each $rec->{LOOKUP}->%*; 739 740 my $answer = $rec->{THATCODE}->($arg); 741 $answer = $rec->{THISCODE}->($arg1, $arg2); 742 743 # careful of extra block braces on fh ref 744 print { $rec->{HANDLE} } "a string\n"; 745 746 use FileHandle; 747 $rec->{HANDLE}->autoflush(1); 748 $rec->{HANDLE}->print(" a string\n"); 749 750=head2 Declaration of a HASH OF COMPLEX RECORDS 751 752 my %TV = ( 753 flintstones => { 754 series => "flintstones", 755 nights => [ qw(monday thursday friday) ], 756 members => [ 757 { name => "fred", role => "lead", age => 36, }, 758 { name => "wilma", role => "wife", age => 31, }, 759 { name => "pebbles", role => "kid", age => 4, }, 760 ], 761 }, 762 763 jetsons => { 764 series => "jetsons", 765 nights => [ qw(wednesday saturday) ], 766 members => [ 767 { name => "george", role => "lead", age => 41, }, 768 { name => "jane", role => "wife", age => 39, }, 769 { name => "elroy", role => "kid", age => 9, }, 770 ], 771 }, 772 773 simpsons => { 774 series => "simpsons", 775 nights => [ qw(monday) ], 776 members => [ 777 { name => "homer", role => "lead", age => 34, }, 778 { name => "marge", role => "wife", age => 37, }, 779 { name => "bart", role => "kid", age => 11, }, 780 ], 781 }, 782 ); 783 784=head2 Generation of a HASH OF COMPLEX RECORDS 785 786 # reading from file 787 # this is most easily done by having the file itself be 788 # in the raw data format as shown above. perl is happy 789 # to parse complex data structures if declared as data, so 790 # sometimes it's easiest to do that 791 792 # here's a piece by piece build up 793 my $rec = {}; 794 $rec->{series} = "flintstones"; 795 $rec->{nights} = [ find_days() ]; 796 797 my @members = (); 798 # assume this file in field=value syntax 799 while (<>) { 800 my %fields = split /[\s=]+/; 801 push @members, { %fields }; 802 } 803 $rec->{members} = [ @members ]; 804 805 # now remember the whole thing 806 $TV{ $rec->{series} } = $rec; 807 808 ########################################################### 809 # now, you might want to make interesting extra fields that 810 # include pointers back into the same data structure so if 811 # change one piece, it changes everywhere, like for example 812 # if you wanted a {kids} field that was a reference 813 # to an array of the kids' records without having duplicate 814 # records and thus update problems. 815 ########################################################### 816 foreach my $family (keys %TV) { 817 my $rec = $TV{$family}; # temp pointer 818 my @kids = (); 819 for my $person ( $rec->{members}->@* ) { 820 if ($person->{role} =~ /kid|son|daughter/) { 821 push @kids, $person; 822 } 823 } 824 # REMEMBER: $rec and $TV{$family} point to same data!! 825 $rec->{kids} = [ @kids ]; 826 } 827 828 # you copied the array, but the array itself contains pointers 829 # to uncopied objects. this means that if you make bart get 830 # older via 831 832 $TV{simpsons}{kids}[0]{age}++; 833 834 # then this would also change in 835 print $TV{simpsons}{members}[2]{age}; 836 837 # because $TV{simpsons}{kids}[0] and $TV{simpsons}{members}[2] 838 # both point to the same underlying anonymous hash table 839 840 # print the whole thing 841 foreach my $family ( keys %TV ) { 842 print "the $family"; 843 print " is on during $TV{$family}{nights}->@*\n"; 844 print "its members are:\n"; 845 for my $who ( $TV{$family}{members}->@* ) { 846 print " $who->{name} ($who->{role}), age $who->{age}\n"; 847 } 848 print "it turns out that $TV{$family}{lead} has "; 849 print scalar ( $TV{$family}{kids}->@* ), " kids named "; 850 print join (", ", map { $_->{name} } $TV{$family}{kids}->@* ); 851 print "\n"; 852 } 853 854=head1 Database Ties 855 856You cannot easily tie a multilevel data structure (such as a hash of 857hashes) to a dbm file. The first problem is that all but GDBM and 858Berkeley DB have size limitations, but beyond that, you also have problems 859with how references are to be represented on disk. One experimental 860module that does partially attempt to address this need is the MLDBM 861module. Check your nearest CPAN site as described in L<perlmodlib> for 862source code to MLDBM. 863 864=head1 SEE ALSO 865 866L<perlref>, L<perllol>, L<perldata>, L<perlobj> 867 868=head1 AUTHOR 869 870Tom Christiansen <F<tchrist@perl.com>> 871