4

I have the following code:

my @array = ('a', 'b', 'c');

my $region = \@array;  # Returns an array reference
my $Value = ${@{$region}}[3];   

I am using strict;

This code passed smoothly in Perl v5.8.6, and now that I installed v5.10.1, I get a runtime error:

Can't use string ("4") as an ARRAY ref while "strict refs" in use at ...

I changed the code to the following, and that solved the issue:

my @array = ('a', 'b', 'c');

my $region = \@Array;
my @List = @{$region};
my $Value = $List[3];   

my question is, what's wrong with the previous way? What has changed between these two versions? What am I missing here?

Thanks, Gal

2
  • 5
    Also what I think the problem is... that your region contains 4 elements, than @{$region} is evaluated in a list context which returns 4 and your call becomes: $Value = ${'4'}[3] which produces the error Commented Aug 14, 2011 at 10:56
  • 2
    Why do you keep referencing the 4th element in a list which is three elements long in the code? Commented Aug 14, 2011 at 11:29

2 Answers 2

11

${@{$region}}[3] was never the correct way to access an arrayref. I'm not quite sure what it does mean, and I don't think Perl is either (hence the different behavior in different versions of Perl).

The correct ways are explained in perlref:

my $Value = ${$region}[3]; # This works with any expression returning an arrayref
my $Value = $$region[3];   # Since $region is a simple scalar variable,
                           # the braces are optional
my $Value = $region->[3];  # This is the way I would do it
Sign up to request clarification or add additional context in comments.

7 Comments

The new behavior is correct; the block after the $ should get scalar context. Older perl versions would erroneously promote the array to an array reference. But I thought this was going through a deprecation cycle - looks like that was done for @array->[] but not ${@array}[] :(
${ @{$region} }[3] is ${ scalar(@{$region}) }[3]. It's equivalent to $0[3], $1[3], $2[3] or similar, depending on the number of elements in @$region.
@Jared Ng, All 3? Only two ways were presented. If you consider adding parens, then there are far more than 3. ${$region}[3], ${region}->[3] and ($region)->[3], for starters.
@ysth, Those curlies don't form a block.
@ysth, as best I can tell, ${@array}[] didn't get a deprecation cycle cause it always worked correctly. (Worked in 5.10, don't have 5.8 anymore) @array->[] was deprecated in 5.12 and fixed in 5.14.
|
2

This is how I would do it:

my @array = ('a', 'b', 'c');
my $region = \@array;
my $Value = $$region[1];
print $Value;

Output:

b

1 Comment

Why exactly did this get a downvote? It's a perfectly valid method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.