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. The best way
279 to 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
302 You can use the debugger's "x" command to dump out complex data
303 structures. For example, given the assignment to $AoA above, here's
304 the debugger output:
305
306 DB<1> x $AoA
307 $AoA = ARRAY(0x13b5a0)
308 0 ARRAY(0x1f0a24)
309 0 'fred'
310 1 'barney'
311 2 'pebbles'
312 3 'bambam'
313 4 'dino'
314 1 ARRAY(0x13b558)
315 0 'homer'
316 1 'bart'
317 2 'marge'
318 3 'maggie'
319 2 ARRAY(0x13b540)
320 0 'george'
321 1 'jane'
322 2 'elroy'
323 3 'judy'
324
326 Presented with little comment here are short code examples illustrating
327 access of various types of data structures.
328
330 Declaration of an ARRAY OF ARRAYS
331 @AoA = (
332 [ "fred", "barney" ],
333 [ "george", "jane", "elroy" ],
334 [ "homer", "marge", "bart" ],
335 );
336
337 Generation of an ARRAY OF ARRAYS
338 # reading from file
339 while ( <> ) {
340 push @AoA, [ split ];
341 }
342
343 # calling a function
344 for $i ( 1 .. 10 ) {
345 $AoA[$i] = [ somefunc($i) ];
346 }
347
348 # using temp vars
349 for $i ( 1 .. 10 ) {
350 @tmp = somefunc($i);
351 $AoA[$i] = [ @tmp ];
352 }
353
354 # add to an existing row
355 push $AoA[0]->@*, "wilma", "betty";
356
357 Access and Printing of an ARRAY OF ARRAYS
358 # one element
359 $AoA[0][0] = "Fred";
360
361 # another element
362 $AoA[1][1] =~ s/(\w)/\u$1/;
363
364 # print the whole thing with refs
365 for $aref ( @AoA ) {
366 print "\t [ @$aref ],\n";
367 }
368
369 # print the whole thing with indices
370 for $i ( 0 .. $#AoA ) {
371 print "\t [ $AoA[$i]->@* ],\n";
372 }
373
374 # print the whole thing one at a time
375 for $i ( 0 .. $#AoA ) {
376 for $j ( 0 .. $AoA[$i]->$#* ) {
377 print "elem at ($i, $j) is $AoA[$i][$j]\n";
378 }
379 }
380
382 Declaration of a HASH OF ARRAYS
383 %HoA = (
384 flintstones => [ "fred", "barney" ],
385 jetsons => [ "george", "jane", "elroy" ],
386 simpsons => [ "homer", "marge", "bart" ],
387 );
388
389 Generation of a HASH OF ARRAYS
390 # reading from file
391 # flintstones: fred barney wilma dino
392 while ( <> ) {
393 next unless s/^(.*?):\s*//;
394 $HoA{$1} = [ split ];
395 }
396
397 # reading from file; more temps
398 # flintstones: fred barney wilma dino
399 while ( $line = <> ) {
400 ($who, $rest) = split /:\s*/, $line, 2;
401 @fields = split ' ', $rest;
402 $HoA{$who} = [ @fields ];
403 }
404
405 # calling a function that returns a list
406 for $group ( "simpsons", "jetsons", "flintstones" ) {
407 $HoA{$group} = [ get_family($group) ];
408 }
409
410 # likewise, but using temps
411 for $group ( "simpsons", "jetsons", "flintstones" ) {
412 @members = get_family($group);
413 $HoA{$group} = [ @members ];
414 }
415
416 # append new members to an existing family
417 push $HoA{flintstones}->@*, "wilma", "betty";
418
419 Access and Printing of a HASH OF ARRAYS
420 # one element
421 $HoA{flintstones}[0] = "Fred";
422
423 # another element
424 $HoA{simpsons}[1] =~ s/(\w)/\u$1/;
425
426 # print the whole thing
427 foreach $family ( keys %HoA ) {
428 print "$family: $HoA{$family}->@* \n"
429 }
430
431 # print the whole thing with indices
432 foreach $family ( keys %HoA ) {
433 print "family: ";
434 foreach $i ( 0 .. $HoA{$family}->$#* ) {
435 print " $i = $HoA{$family}[$i]";
436 }
437 print "\n";
438 }
439
440 # print the whole thing sorted by number of members
441 foreach $family ( sort { $HoA{$b}->@* <=> $HoA{$a}->@* } keys %HoA ) {
442 print "$family: $HoA{$family}->@* \n"
443 }
444
445 # print the whole thing sorted by number of members and name
446 foreach $family ( sort {
447 $HoA{$b}->@* <=> $HoA{$a}->@*
448 ||
449 $a cmp $b
450 } keys %HoA )
451 {
452 print "$family: ", join(", ", sort $HoA{$family}->@* ), "\n";
453 }
454
456 Declaration of an ARRAY OF HASHES
457 @AoH = (
458 {
459 Lead => "fred",
460 Friend => "barney",
461 },
462 {
463 Lead => "george",
464 Wife => "jane",
465 Son => "elroy",
466 },
467 {
468 Lead => "homer",
469 Wife => "marge",
470 Son => "bart",
471 }
472 );
473
474 Generation of an ARRAY OF HASHES
475 # reading from file
476 # format: LEAD=fred FRIEND=barney
477 while ( <> ) {
478 $rec = {};
479 for $field ( split ) {
480 ($key, $value) = split /=/, $field;
481 $rec->{$key} = $value;
482 }
483 push @AoH, $rec;
484 }
485
486
487 # reading from file
488 # format: LEAD=fred FRIEND=barney
489 # no temp
490 while ( <> ) {
491 push @AoH, { split /[\s+=]/ };
492 }
493
494 # calling a function that returns a key/value pair list, like
495 # "lead","fred","daughter","pebbles"
496 while ( %fields = getnextpairset() ) {
497 push @AoH, { %fields };
498 }
499
500 # likewise, but using no temp vars
501 while (<>) {
502 push @AoH, { parsepairs($_) };
503 }
504
505 # add key/value to an element
506 $AoH[0]{pet} = "dino";
507 $AoH[2]{pet} = "santa's little helper";
508
509 Access and Printing of an ARRAY OF HASHES
510 # one element
511 $AoH[0]{lead} = "fred";
512
513 # another element
514 $AoH[1]{lead} =~ s/(\w)/\u$1/;
515
516 # print the whole thing with refs
517 for $href ( @AoH ) {
518 print "{ ";
519 for $role ( keys %$href ) {
520 print "$role=$href->{$role} ";
521 }
522 print "}\n";
523 }
524
525 # print the whole thing with indices
526 for $i ( 0 .. $#AoH ) {
527 print "$i is { ";
528 for $role ( keys $AoH[$i]->%* ) {
529 print "$role=$AoH[$i]{$role} ";
530 }
531 print "}\n";
532 }
533
534 # print the whole thing one at a time
535 for $i ( 0 .. $#AoH ) {
536 for $role ( keys $AoH[$i]->%* ) {
537 print "elem at ($i, $role) is $AoH[$i]{$role}\n";
538 }
539 }
540
542 Declaration of a HASH OF HASHES
543 %HoH = (
544 flintstones => {
545 lead => "fred",
546 pal => "barney",
547 },
548 jetsons => {
549 lead => "george",
550 wife => "jane",
551 "his boy" => "elroy",
552 },
553 simpsons => {
554 lead => "homer",
555 wife => "marge",
556 kid => "bart",
557 },
558 );
559
560 Generation of a HASH OF HASHES
561 # reading from file
562 # flintstones: lead=fred pal=barney wife=wilma pet=dino
563 while ( <> ) {
564 next unless s/^(.*?):\s*//;
565 $who = $1;
566 for $field ( split ) {
567 ($key, $value) = split /=/, $field;
568 $HoH{$who}{$key} = $value;
569 }
570
571
572 # reading from file; more temps
573 while ( <> ) {
574 next unless s/^(.*?):\s*//;
575 $who = $1;
576 $rec = {};
577 $HoH{$who} = $rec;
578 for $field ( split ) {
579 ($key, $value) = split /=/, $field;
580 $rec->{$key} = $value;
581 }
582 }
583
584 # calling a function that returns a key,value hash
585 for $group ( "simpsons", "jetsons", "flintstones" ) {
586 $HoH{$group} = { get_family($group) };
587 }
588
589 # likewise, but using temps
590 for $group ( "simpsons", "jetsons", "flintstones" ) {
591 %members = get_family($group);
592 $HoH{$group} = { %members };
593 }
594
595 # append new members to an existing family
596 %new_folks = (
597 wife => "wilma",
598 pet => "dino",
599 );
600
601 for $what (keys %new_folks) {
602 $HoH{flintstones}{$what} = $new_folks{$what};
603 }
604
605 Access and Printing of a HASH OF HASHES
606 # one element
607 $HoH{flintstones}{wife} = "wilma";
608
609 # another element
610 $HoH{simpsons}{lead} =~ s/(\w)/\u$1/;
611
612 # print the whole thing
613 foreach $family ( keys %HoH ) {
614 print "$family: { ";
615 for $role ( keys $HoH{$family}->%* ) {
616 print "$role=$HoH{$family}{$role} ";
617 }
618 print "}\n";
619 }
620
621 # print the whole thing somewhat sorted
622 foreach $family ( sort keys %HoH ) {
623 print "$family: { ";
624 for $role ( sort keys $HoH{$family}->%* ) {
625 print "$role=$HoH{$family}{$role} ";
626 }
627 print "}\n";
628 }
629
630
631 # print the whole thing sorted by number of members
632 foreach $family ( sort { $HoH{$b}->%* <=> $HoH{$a}->%* } keys %HoH ) {
633 print "$family: { ";
634 for $role ( sort keys $HoH{$family}->%* ) {
635 print "$role=$HoH{$family}{$role} ";
636 }
637 print "}\n";
638 }
639
640 # establish a sort order (rank) for each role
641 $i = 0;
642 for ( qw(lead wife son daughter pal pet) ) { $rank{$_} = ++$i }
643
644 # now print the whole thing sorted by number of members
645 foreach $family ( sort { $HoH{$b}->%* <=> $HoH{$a}->%* } keys %HoH ) {
646 print "$family: { ";
647 # and print these according to rank order
648 for $role ( sort { $rank{$a} <=> $rank{$b} }
649 keys $HoH{$family}->%* )
650 {
651 print "$role=$HoH{$family}{$role} ";
652 }
653 print "}\n";
654 }
655
657 Declaration of MORE ELABORATE RECORDS
658 Here's a sample showing how to create and use a record whose fields are
659 of many different sorts:
660
661 $rec = {
662 TEXT => $string,
663 SEQUENCE => [ @old_values ],
664 LOOKUP => { %some_table },
665 THATCODE => \&some_function,
666 THISCODE => sub { $_[0] ** $_[1] },
667 HANDLE => \*STDOUT,
668 };
669
670 print $rec->{TEXT};
671
672 print $rec->{SEQUENCE}[0];
673 $last = pop $rec->{SEQUENCE}->@*;
674
675 print $rec->{LOOKUP}{"key"};
676 ($first_k, $first_v) = each $rec->{LOOKUP}->%*;
677
678 $answer = $rec->{THATCODE}->($arg);
679 $answer = $rec->{THISCODE}->($arg1, $arg2);
680
681 # careful of extra block braces on fh ref
682 print { $rec->{HANDLE} } "a string\n";
683
684 use FileHandle;
685 $rec->{HANDLE}->autoflush(1);
686 $rec->{HANDLE}->print(" a string\n");
687
688 Declaration of a HASH OF COMPLEX RECORDS
689 %TV = (
690 flintstones => {
691 series => "flintstones",
692 nights => [ qw(monday thursday friday) ],
693 members => [
694 { name => "fred", role => "lead", age => 36, },
695 { name => "wilma", role => "wife", age => 31, },
696 { name => "pebbles", role => "kid", age => 4, },
697 ],
698 },
699
700 jetsons => {
701 series => "jetsons",
702 nights => [ qw(wednesday saturday) ],
703 members => [
704 { name => "george", role => "lead", age => 41, },
705 { name => "jane", role => "wife", age => 39, },
706 { name => "elroy", role => "kid", age => 9, },
707 ],
708 },
709
710 simpsons => {
711 series => "simpsons",
712 nights => [ qw(monday) ],
713 members => [
714 { name => "homer", role => "lead", age => 34, },
715 { name => "marge", role => "wife", age => 37, },
716 { name => "bart", role => "kid", age => 11, },
717 ],
718 },
719 );
720
721 Generation of a HASH OF COMPLEX RECORDS
722 # reading from file
723 # this is most easily done by having the file itself be
724 # in the raw data format as shown above. perl is happy
725 # to parse complex data structures if declared as data, so
726 # sometimes it's easiest to do that
727
728 # here's a piece by piece build up
729 $rec = {};
730 $rec->{series} = "flintstones";
731 $rec->{nights} = [ find_days() ];
732
733 @members = ();
734 # assume this file in field=value syntax
735 while (<>) {
736 %fields = split /[\s=]+/;
737 push @members, { %fields };
738 }
739 $rec->{members} = [ @members ];
740
741 # now remember the whole thing
742 $TV{ $rec->{series} } = $rec;
743
744 ###########################################################
745 # now, you might want to make interesting extra fields that
746 # include pointers back into the same data structure so if
747 # change one piece, it changes everywhere, like for example
748 # if you wanted a {kids} field that was a reference
749 # to an array of the kids' records without having duplicate
750 # records and thus update problems.
751 ###########################################################
752 foreach $family (keys %TV) {
753 $rec = $TV{$family}; # temp pointer
754 @kids = ();
755 for $person ( $rec->{members}->@* ) {
756 if ($person->{role} =~ /kid|son|daughter/) {
757 push @kids, $person;
758 }
759 }
760 # REMEMBER: $rec and $TV{$family} point to same data!!
761 $rec->{kids} = [ @kids ];
762 }
763
764 # you copied the array, but the array itself contains pointers
765 # to uncopied objects. this means that if you make bart get
766 # older via
767
768 $TV{simpsons}{kids}[0]{age}++;
769
770 # then this would also change in
771 print $TV{simpsons}{members}[2]{age};
772
773 # because $TV{simpsons}{kids}[0] and $TV{simpsons}{members}[2]
774 # both point to the same underlying anonymous hash table
775
776 # print the whole thing
777 foreach $family ( keys %TV ) {
778 print "the $family";
779 print " is on during $TV{$family}{nights}->@*\n";
780 print "its members are:\n";
781 for $who ( $TV{$family}{members}->@* ) {
782 print " $who->{name} ($who->{role}), age $who->{age}\n";
783 }
784 print "it turns out that $TV{$family}{lead} has ";
785 print scalar ( $TV{$family}{kids}->@* ), " kids named ";
786 print join (", ", map { $_->{name} } $TV{$family}{kids}->@* );
787 print "\n";
788 }
789
791 You cannot easily tie a multilevel data structure (such as a hash of
792 hashes) to a dbm file. The first problem is that all but GDBM and
793 Berkeley DB have size limitations, but beyond that, you also have
794 problems with how references are to be represented on disk. One
795 experimental module that does partially attempt to address this need is
796 the MLDBM module. Check your nearest CPAN site as described in
797 perlmodlib for source code to MLDBM.
798
800 perlref, perllol, perldata, perlobj
801
803 Tom Christiansen <tchrist@perl.com>
804
805
806
807perl v5.34.0 2021-10-18 PERLDSC(1)