Perl Cookbook

Perl CookbookSearch this book
Previous: 10.4. Determining Current Function NameChapter 10
Subroutines
Next: 10.6. Detecting Return Context
 

10.5. Passing Arrays and Hashes by Reference

Problem

You want to pass a function more than one array or hash and have each remain distinct. For example, you want to put the "Find elements in one array but not in another" algorithm from Recipe 4.7 in a subroutine. This subroutine must then be called with two arrays that remain distinct.

Solution

Pass arrays and hashes by reference, using the backslash operator:

array_diff( \@array1, \@array2 );

Discussion

See Chapter 11, References and Records, for more about manipulation of references. Here's a subroutine that takes array references and a subroutine call that generates them:

@a = (1, 2);
@b = (5, 8);
@c = add_vecpair( \@a, \@b );
print "@c\n";
6 10 

sub add_vecpair {       # assumes both vectors the same length
    my ($x, $y) = @_;   # copy in the array references
    my @result;

    for (my $i=0; $i < @$x; $i++) {
      $result[$i] = $x->[$i] + $y->[$i];
    }

    return @result;
}

A potential difficulty with this function is that it doesn't check to make sure it got exactly two arguments that were both array references. You could check explicitly this way:

unless (@_ == 2 && ref($x) eq 'ARRAY' && ref($y) eq 'ARRAY') {
    die "usage: add_vecpair ARRAYREF1 ARRAYREF2";
}

If all you plan to do is die on error (see Recipe 10.12), you can usually omit this check, since dereferencing the wrong kind of reference triggers an exception anyway.

See Also

The section on "Passing References" in Chapter 2 of Programming Perl and on "Pass by Reference" in perlsub (1); the section on "Prototypes" in Chapter 2 of Programming Perl or in perlsub (1); Recipe 10.11; Chapter 11; Chapter 4 of Programming Perl.


Previous: 10.4. Determining Current Function NamePerl CookbookNext: 10.6. Detecting Return Context
10.4. Determining Current Function NameBook Index10.6. Detecting Return Context