Search code examples
arraysperllistreferenceperl-data-structures

Array context assignment to empty list reference in Perl-- please explain the line " my @arr = [ ]; "


I'm new to Perl. I understand that my @a = (); is equivalent to my @a;-- both initialize an empty array. Similarly, my $a = []; initializes an empty array that's referenced by $a.

However, I'm perplexed by my @arr = []; which is also legal Perl. According to ref() and print, @arr is an array, not a reference to one. It can be pushed onto, which seems to return the number of elements in the array. But it seems to contain a reference to another array, which can also be pushed onto:

#!/usr/bin/perl
use v5.16;

my @arr = [];
push(@arr, 1);

print join(", ", @arr) . "\n";

push(@arr[0], 11);
push(@arr[0], 12);

print "a[0]: " . join(", ", @{@arr[0]}) . "\n";

Outputs

ARRAY(0xd6ede8), 1
a[0]: 11, 12

What is going on here? Detail is greatly appreciated.


Solution

  • Your understanding is correct.

    The [] always creates an array reference, and references always are scalars. Here, my @arr = [] (or equivalently: my @arr = ([])) creates an array @arr with the first element being an array reference.

    Scalars are never context-dependent! Context only matters for

    • hash or array variables: @foo and %foo
    • subroutine calls, as a call propagates the current context and can be queried via wantarray. Subroutines may therefore behave differently in various context.
    • operators, as some operators like , or .. are entirely different depending on context.