I would recommend against excessive use of statements like this:
$array1_ref = \@array1; Sometimes this is not necessary and just
obscures the code's intent.
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;
}
|