Reputation: 501
I do not understand what is going on with this short segment of code.
I have put the output and comments about it in the middle, after the print statements which produce it.
my @regions = (
0,
1,
2,
[ 0, new Point(3,1), new Point(3,2), new Point(3,3) ],
4,
5 );
$reg1 = 3;
print "1: $regions[$reg1] \n";
@reg1 = @{regions[$reg1]};
print "2: $reg1[0]\n";
print "3: $reg1[0][1]\n";
print "4: ", Point::stringPoint($reg1[0][1]), "\n";
# HERE IS THE OUTPUT from the above print statements, with comments about my confusion appended
1: ARRAY(0xe8b0e0) # ok - element 3 of @regions is an array, as expected.
2: ARRAY(0xe8b0e0) # It appears to be an array of one element, which is itself. ???
3: Point=HASH(0xfda5e0) # We have go 'down' one more level to get what we want - that makes no sense
4: 3,1 # Yes, there it is
package Point;
sub new {
my $class = shift;
my $self = {
x => shift,
y => shift
};
bless $self, $class;
return $self;
}
sub stringPoint
{
my $p = shift;
return "$p->{x},$p->{y}";
}
" Code related to new question (with output) " ;
The real question I have is this:
How to work directly and conveniently with an array,
which is inside another array (not a copy of it) ?
Is the only way to do that by (always) de-referencing a reference?
Such as in the two non-working examples which follow.
Here is what I tried:
my $ref1 = \@{$regions[3]};
@{$ref1}[2] = new Point(4, 5); # changes original array
print1Region(3, $ref1);
# OUTPUT = (3,1) (4,5) (3,3)
my @arr1 = @{$ref1};
$arr1[1] = new Point(2,6); # does not
print1Region(3, $ref1);
# OUTPUT = (3,1) (4,5) (3,3)
$ref1[0] = new Point(1,4); # does not
print1Region(3, $ref1);
# OUTPUT = (3,1) (4,5) (3,3)
Upvotes: 1
Views: 85
Reputation: 385506
@{regions[$reg1]}
is a weird and undocumented way of writing @regions[$reg1]
. (It's a syntax documented for use in double-quoted string literals.)
@regions[$reg1]
is an array slice with one element, which is a weird way of writing $regions[$reg1]
.
So you aren't getting the first element of the array referenced by $regions[$reg1]
as you think you are; you are simply getting the first element of @regions
.
Let's look at
my $ref1 = \@{$regions[3]};
@{$ref1}[2] = new Point(4, 5);
Problem #1
\@
"cancel out", so
my $ref1 = \@{$regions[3]};
is just a complicated way of writing
my $ref1 = $regions[3];
(Ok, that's not quite true because the former autovivifies, but that's not relevant here.)
Problem #2
Again you're using an array slice of one element. ALWAYS use use strict; use warnings;
and heed the warnings!
@{$ref1}[2] = new Point(4, 5);
should be
${$ref1}[2] = new Point(4, 5);
which is more cleanly written using the "arrow notation".
$ref1->[2] = new Point(4, 5);
Problem #3
Finally, don't use indirect method calls. They cause issues.
$ref1->[2] = new Point(4, 5);
should be
$ref1->[2] = Point->new(4, 5);
Conclusion
my $ref1 = \@{$regions[3]};
@{$ref1}[2] = new Point(4, 5);
should be written as
my $ref1 = $regions[3];
$ref1->[2] = Point->new(4, 5);
Without the variable, this would be
$regions[3]->[2] = Point->new(4, 5);
or just
$regions[3][2] = Point->new(4, 5);
Upvotes: 4