11.1. Taking References to Arrays
11.1.1. Problem
You need to manipulate an array by
reference.
11.1.2. Solution
To get a reference to an array:
$aref = \@array;
$anon_array = [1, 3, 5, 7, 9];
$anon_copy = [ @array ];
@$implicit_creation = (2, 4, 6, 8, 10);
To deference an array reference, precede it with an at sign
(@):
push(@$anon_array, 11);
Or use a pointer arrow plus a bracketed subscript for a particular
element:
$two = $implicit_creation->[0];
To get the last index number by reference, or the number of items in
that referenced array:
$last_idx = $#$aref;
$num_items = @$aref;
Or defensively embracing and forcing context:
$last_idx = $#{ $aref };
$num_items = scalar @{ $aref };
11.1.3. Discussion
Here are array references in action:
# check whether $someref contains a simple array reference
if (ref($someref) ne "ARRAY") {
die "Expected an array reference, not $someref\n";
}
print "@{$array_ref}\n";
# print original data
@order = sort @{ $array_ref };
# sort it
push @{ $array_ref }, $item;
# append new element to orig array
If you can't decide whether to use a reference to a named array or to
create a new one, here's a simplistic guideline that will prove right
more often than not. Only take a reference to an existing array to
return the reference out of scope, thereby creating an anonymous
array, or to pass the array by reference to a function. For virtually
all other cases, use [@array] to create a new
array reference with a copy of the old values.Automatic reference counting and the backslash operator make a
powerful combination:
sub array_ref {
my @array;
return \@array;
}
$aref1 = array_ref( );
$aref2 = array_ref( );
Each time array_ref is called, the function
allocates a new piece of memory for @array. If we
hadn't returned a reference to @array, its memory
would have been freed when its block, the subroutine, ended. But here
a reference to @array is still accessible, so Perl
doesn't free that storage, and we wind up with a reference to a piece
of memory no longer accessible through the symbol table. Such a piece
of memory is called anonymous because it has
no name associated with it.To access a particular element of the array referenced by
$aref, you could write
$$aref[4], but $aref->[4] is
the same thing, and clearer.
print $array_ref->[$N];
# access item in position N (best)
print $$array_ref[$N];
# same, but confusing
print ${$array_ref}[$N];
# same, but still confusing, and ugly to boot
If you have an array reference, you can only access a slice of the
referenced array in this way:
@$pie[3..5];
# array slice, but a little confusing to read
@{$pie}[3..5];
# array slice, easier (?) to read
Array slices, even when accessed through array references, are
assignable. In the next line, the array dereference happens first,
then the slice:
@{$pie}[3..5] = ("blackberry", "blueberry", "pumpkin");
An array slice is just syntactic sugar for a list of individual array
elements. Because you can't take a reference to a list, you can't
take a reference to an array slice:
$sliceref = \@{$pie}[3..5]; # WRONG!
To iterate through the entire array, loop with
foreach or for:
foreach $item ( @{$array_ref} ) {
# $item has data
}
for ($idx = 0; $idx <= $#{ $array_ref }; $idx++) {
# $array_ref->[$idx] has data
}
11.1.4. See Also
Chapters 8 and 9 of Programming Perl;
perlref(1), perlreftut(1),
and perllol(1); Recipe 2.13; Recipe 4.6