Anonymous references — [...] and {...}#

You don’t always want to give an inner array or hash a name before you reference it. Perl provides two constructors that build a new container and hand you a reference to it in a single expression:

  • [...] builds a fresh anonymous array and returns a reference to it.

  • {...} builds a fresh anonymous hash and returns a reference to it.

These are the primary way nested data structures are assembled.

Array: [...]#

my $aref = [1, 'foo', undef, 13];

The right-hand side evaluates the list (1, 'foo', undef, 13), allocates a new array, copies those four elements in, and yields a scalar holding a reference to that array. This is exactly equivalent to the two-step form with a named intermediate:

my @array = (1, 'foo', undef, 13);
my $aref  = \@array;

…except that no @array variable leaks into the surrounding scope. The anonymous array has no name; only the reference exists, and the array stays alive as long as the reference does.

Empty forms are useful as initial values:

my $aref = [];         # reference to a new empty array
push @{$aref}, 1, 2;   # now [1, 2]

Hash: {...}#

my $href = { APR => 4, AUG => 8 };

Same idea for hashes. The expression is a list of key/value pairs (the => is just a comma that auto-quotes its left side), a new hash is allocated, the pairs are inserted, and you get a reference back:

my %hash = (APR => 4, AUG => 8);
my $href = \%hash;

is the two-step equivalent. And as with arrays, the empty form is a common starting point:

my $href = {};
$href->{red} = 17;

{...} vs. block — a parser corner#

A bare {...} at statement position is parsed as a block, not as a hash constructor:

{ foo => 1 };          # block, with `foo => 1` as its expression

In most positions — on the right of =, inside a list, as an argument to a function — Perl figures out the hash-constructor reading automatically. If you ever need to force the hash-constructor interpretation, put + in front:

my $x = +{ foo => 1 }; # unambiguous: always a hash reference

You’ll rarely need this. Inside return +{...} from a subroutine and in a few other “statement-like” positions, it’s the fix.

Nesting — constructors inside constructors#

Because each constructor yields a scalar, and scalars go anywhere, you compose structures by nesting:

my $tree = {
    name     => 'root',
    children => [
        { name => 'left',  children => [] },
        { name => 'right', children => [
            { name => 'r1', children => [] },
        ] },
    ],
};

print $tree->{children}[1]{children}[0]{name};   # r1

Every [...] and {...} allocates fresh. Unlike the “shared-inner-array” footgun from Arrays of arrays, nested constructors never share storage by accident.

Named intermediates vs. anonymous constructors#

Both forms work. Pick based on readability:

  • Anonymous constructor when the container is single-purpose and its only role is “be the value of this field”. Nested data literals, one-off lookup tables, callback-table entries.

  • Named intermediate when you’re building the container incrementally, or when you want to use array/hash operators on it directly without repeating @{...} / %{...}:

    my @row;
    for my $x (@source) {
        push @row, transform($x);
    }
    $grid[$i] = \@row;
    

Copying vs. sharing#

Anonymous constructors always allocate; they never share. But assigning one reference to another scalar does not duplicate anything:

my $a = [1, 2, 3];
my $b = $a;            # $a and $b refer to the SAME array
push @{$b}, 4;
print "@{$a}";         # 1 2 3 4

To get a shallow copy of the underlying container, dereference inside a fresh constructor:

my $copy_aref = [ @{$a} ];     # new array, same elements
my $copy_href = { %{$h} };     # new hash, same keys/values

The new reference is independent of the original. The values inside are still shared — if those values are themselves references, the two structures still point at common subtrees. That’s shallow copying. For deep copying, reach for a module like Storable (dclone).

Where to go next#

  • Subroutine references — the third flavour of anonymous thing, using sub { ... } instead of [...] or {...}.

  • Weak references — needed when a nested structure points back at itself.