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