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.