Syntactic Confectionery Delight PerlMonks

### Problem Defining AoA from Named AoA

 on Jan 13, 2007 at 10:21 UTC Need Help??
adeirossi has asked for the wisdom of the Perl Monks concerning the following question:

I'm a Perl beginner having trouble with arrays of arrays. When I define an AoA using a named AoA, both array names seem to refer to the same AoA. For example, if I first define @aoa1 with an anonymous AoA and then define @aoa2 with "my @aoa2 = @aoa1;", the modification of @aoa2 undesirably modifies @aoa1 (and vice versa).

The script below demonstrates this problem:
```    use strict;
use warnings;

my @aoa1 = (                  # define @aoa1 w/ anonymous AoA
["-","-","-"],
["-","-","-"],
["-","-","-"],
);

# my @aoa2 = (                # define @aoa2 w/ anonymous AoA
#         ["-","-","-"],
#         ["-","-","-"],
#         ["-","-","-"],
#     );

my @aoa2 = @aoa1;             # define @aoa2 w/ named AoA

# \$aoa1[1][1] = '@';          # modify @aoa1

\$aoa2[1][1] = '@';            # modify @aoa2

printAoa( "aoa1", @aoa1 );    # print @aoa1
printAoa( "aoa2", @aoa2 );    # print @aoa2

exit;

sub printAoa {
my ( \$aoaName, @aoa ) = @_;
my \$row;
my \$col;

print "*** \$aoaName ***\n";

for \$row ( 0 .. 2 ) {
for \$col ( 0 .. 2 ) {
print "\$aoa[\$row][\$col] ";
}
print "\n";
}
print "\n";
}
I would expect the above script to print:
```    *** @aoa1 ***
- - -
- - -
- - -

*** @aoa2 ***
- - -
- @ -
- - -
```    *** @aoa1 ***
- - -
- @ -
- - -

*** @aoa2 ***
- - -
- @ -
- - -
It's as if @aoa1 and @aoa2 refer to the same AoA. When "\$aoa2[1][1] = '@';" is commented out and "\$aoa1[1][1] = '@';" is activated, the output is the same.

The only way I can get @aoa1 and @aoa2 to behave as I'd like is to define both of them with anonymous AoA's. If you comment out "my @aoa2 = @aoa1;" and uncomment the lines above it, the script produces the desired output. This is all well and good, but in my actual script, I need to define AoA's from named AoA's rather than anonymous ones.

Any suggestions would be greatly appreciated.

Thanks,
Andrew

Replies are listed 'Best First'.
Re: Problem Defining AoA from Named AoA
by bsdz (Friar) on Jan 13, 2007 at 11:28 UTC
I must admit this is not very intuitive. Although the wrapper list @aoa1 and @aoa2 point to different locations in memory the internal array references do not. This can be shown by doing something like this: -
```# these will be different
#
print \@aoa1."\n";
print \@aoa2."\n";

# but these won't be!
#
print \$aoa1[0]."\n";
print \$aoa2[0]."\n";

print \$aoa1[1]."\n";
print \$aoa2[1]."\n";

print \$aoa1[2]."\n";
print \$aoa2[2]."\n";
You can get around this by using a deep clone, i.e.
```use strict;
use warnings;
use Storable qw(dclone);
use Data::Dumper;

# define @aoa1 w/ anonymous AoA
#
my @aoa1 = map { [qw(- - -)] } 0..2;

# deep clone @aoa1 to create @aoa2
#
my @aoa2 = @{dclone(\@aoa1)};

# modify @aoa2
#
\$aoa2[1][1] = '@';

# display structures
#
print Dumper(\@aoa1);
print Dumper(\@aoa2);

Perhaps this information should be added to the Array Tutorial.
Re: Problem Defining AoA from Named AoA
by bart (Canon) on Jan 13, 2007 at 12:01 UTC
Both arrays are (different) flat arrays of items. They contain references — the same references. At least, references that point to the same thing. And if two variables hold a reference that points to the same thing, they're almost like aliases (different variables that act as if they're one and the same variable with a different name).*

What you want to investigate is what they call a deep copy or deep cloning. I recall merlyn wrote a magazine article or two about them. See UR col 30.

Also check out Storable, a standard module that includes a function for deep copying: dclone.

p.s. The difference between variables containing the same reference, and aliases, is just this: only a direct full assignment to one of the variables, will break the interconnection. Let me give an example:

```\$x = { a => 1 };   # a reference
\$y = \$x;           # a copy of a reference points to the same thing
\$y->{a}++;         # increments \$x->{a}
\$y->{b} = 3;       # adds a hash item \$x->{b}
\$y = { c => 0 };   # breaks the connection between \$x and \$y
\$y->{c}++;         # no effect on \$x
Re: Problem Defining AoA from Named AoA
by madbombX (Hermit) on Jan 13, 2007 at 16:45 UTC

Create A New User
Node Status?
node history
Node Type: perlquestion [id://594516]
Approved by bsdz
help
Chatterbox?
 [LanX]: YM: talking about breaches ... did you read about Cambridge Analytica harvesting 50e6 FB profiles for political propaganda? LanX ... oh ... Brexit delayed ... again ... oh wonder ... [Your Mother]: Heh. I keeping seeing related headlines but my narcissism is a perihelion right now so I'm busy. :P [Your Mother]: s/a /at /; [LanX]: just watch the video ... [Your Mother]: Roger, will co.

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (11)
As of 2018-03-19 13:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
When I think of a mole I think of:

Results (240 votes). Check out past polls.

Notices?