2

I have the following three assignments, of which the second one looks non-standard:

my $realRef = [1, 2, 3];
my @nonRef  = [4, 5, 6];
my $nonRef  = [7, 8, 9];

The second one should really be the following instead:

my @nonRef  = (4, 5, 6);

When printing, all three variables contain array references and especially the same named variables only differing in @ and $ don't share the same data or overwrite each other.

Ref: ARRAY(0x1fd6a8); $VAR1 = [
          1,
          2,
          3
        ];
Ref: ARRAY(0x6445d8); $VAR1 = [
          4,
          5,
          6
        ];
Ref: ARRAY(0x644740); $VAR1 = [
          7,
          8,
          9
        ];

Why is @nonRefcontaining an array reference at all? Is that stored in $nonRef of the symbol table entry for nonRef or something like that? And why do values of @nonRef and $nonRef don't overlap? Aren't both referencing the same symbol table entry only with different slots, ARRAY vs. SCALAR? Because both store references in the end, I would have expected that the same symbol table entry with the slot SCALAR is used.

Thanks!

3
  • 2
    Parens merely override precedence. They don't create any kind of value/variable like [] and {} do. Commented Jul 9, 2020 at 18:13
  • The official docs say so as well, even though I find the explicit first example (LIST) confusing. That looks like the parentheses are required, but they are not: List values are denoted by separating individual values by commas ([...]): perldoc.perl.org/perldata.html#List-value-constructors Commented Jul 10, 2020 at 6:25
  • 1
    They are required in the specifically mentioned situation for the reason showed in my answer. (my @a = 4,5,6; and my @a = (4,5,6) are not equivalent because of the low precedence of ,.) The doc to which you linked is phrased misleadingly, though. Commented Jul 10, 2020 at 6:26

2 Answers 2

5

The second one is the same as my @nonRef = ([4, 5, 6]) — that is, you're just putting your arrayref into $nonRef[0].

Sign up to request clarification or add additional context in comments.

2 Comments

I see. Because I used Dumper(@nonRef) instead of Dumper(\@nonRef) things looked the same as for Dumper($realRef). That seems pretty confusing to me, because @nonRef = [...], [...] doesn't work as easily and is at least warned about. I would have preferred a compile time error.
@ThorstenSchöning the () isn't a list constructor, it's just the usual precedence-grouping operator. When you do @array = [...], [...] the comma binds too loosely (i.e. (@array = [...]), [...]), which is why we use parens. But the mistaken one isn't invalid syntax, even if it's 99.99% useless.
2

You are creating a one-element array that consists of a reference to an array.


However many scalars you assign to the array is how many elements the array will have.

my @a = 4;
# my @a;
# $a[0] = 4;

my @a = 4..6;
# my @a;
# $a[0] = 4;
# $a[1] = 5;
# $a[2] = 6;

[4, 5, 6] produces one scalar (a reference to an array), so my @nonRef = [4, 5, 6]; creates an array that contains one value (the reference).

my @nonRef = [4, 5, 6];
# my @nonRef;
# $nonRef[0] = [4, 5, 6];

Note the complete lack of parens in the above examples. Parens don't create any kind of value/variable like [] and {} do. They merely override precedence like in mathematics. They are by no means necessary on the right-hand side of an assignment to an array. The only reason we commonly see them on the right hand side of assignments is because

my @a = 4, 5, 6;

is equivalent to

( my @a = 4 ), 5, 6;   # Only assigns 4 to the array.

For a sub without prototypes,

f(@a)

is the same as

f($a[0], $a[1], ...)

So when you did

print(Dumper(@nonRef));

it's as if you did

print(Dumper($nonRef[0]));

I prefer to use

print(Dumper(\@nonRef));

Comments

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.