Taking References to Arrays (Perl Cookbook, 2nd Edition)

## 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

Copyright © 2003 O'Reilly & Associates. All rights reserved.