A more typical thing would be like I show in Example 1. For data, I just made some random numbers to keep things simple.
This code [@array1] means: create an array reference to some newly allocated memory which has no name (anonymous memory) and copy @array1 into that new memory. This is called a deep copy. From the printout, you will see that this works, The data in set B is different than the data in set A (nothing got overwritten). Note that the code does not contain any statements like: $array1_ref = \@array1;
Example 2 is interesting. Whoa! Why did it work? It looks like it shouldn't but it did. The reason is the "my @array" declarations. When Perl runs across a "my" statement you are guaranteed to get a brand new one even if you've been past this statement before. If possible Perl will reuse memory. In this case it couldn't because it figures (correctly) that the previous memory is still in use because somebody has a reference to it (its in the hash table.). This is a case where I would normally use [ ] like in example 1. That does require some extra copying, but the clarity is usually "worth it", i.e. normally I would use syntax in Example 1.
Example 3 is a case of completely botched up code. The my declaration is outside the loop and therefore the @array memory is getting re-used...there is no "my" declaration to "save our butt". the printout is a bit confusing to understand, but basically what it is saying is "hey, set Y clobbered set X.
Data::Dumper is very helpful when debugging data structures and here I can see that there is something odd about this X,Y pair of data.
#!/user/bin/perl -w use strict; use Data::Dump qw[pp]; $|=1; my %hash; print "** Example 1 ***\n"; #pretty normal thing to do for my $set('A'..'B') { my @array1 = map { int(rand(100)) }(1..2); my @array2 = map { int(rand(100)) }(1..5); $hash{$set} = [ [@array1], [@array2] ]; } pp \%hash; print "** Example 2 ***\n"; #a pitfall here for my $set('G'..'H') { my @array1 = map { int(rand(100)) }(1..2); my @array2 = map { int(rand(100)) }(1..5); $hash{$set} = [ \@array1, \@array2 ]; } pp \%hash; print "** Example ***3\n"; #the wrong thing to do my @x; my @y; for my $set('X'..'Y') { @x = map { int(rand(100)) }(1..2); @y = map { int(rand(100)) }(1..5); $hash{$set} = [ \@x, \@y ]; } pp \%hash; __END__ ** Example 1 *** { A => [[45, 13], [77, 53, 52, 21, 23]], B => [[38, 27], [4, 59, 52, 4, 83]], } ** Example 2 *** { A => [[45, 13], [77, 53, 52, 21, 23]], B => [[38, 27], [4, 59, 52, 4, 83]], G => [[3, 35], [13, 58, 35, 76, 64]], H => [[26, 39], [34, 91, 99, 74, 97]], } ** Example ***3 do { my $a = { A => [[45, 13], [77, 53, 52, 21, 23]], B => [[38, 27], [4, 59, 52, 4, 83]], G => [[3, 35], [13, 58, 35, 76, 64]], H => [[26, 39], [34, 91, 99, 74, 97]], X => [[31, 63], [72, 71, 10, 80, 76]], Y => ['fix', 'fix'], }; $a->{Y}[0] = $a->{X}[0]; $a->{Y}[1] = $a->{X}[1]; $a; }
In reply to Re: saving nested arrays in a hash
by Marshall
in thread saving nested arrays in a hash
by Anonymous Monk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |