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