NodeReaper has asked for the wisdom of the Perl Monks concerning the following question:

Replies are listed 'Best First'.
Re: Returning two arrays..
by jonjacobmoon (Pilgrim) on Jan 04, 2002 at 07:22 UTC
    Why not make an @array of arrays, and return that array. This way you need restricted to two arrays. So,
    push(@allarrays,\@array1); push(@allarrays,\@array2); return \@allarrys;
      This is a good suggestion, and you're on the right track, but I was wondering why you return a reference to the main array. The only ones you really need to make references to are the second level deep. There's not really any need to use more references than will get the job done comfortably.

      I really do like the suggestion to return an array of array references, though, instead of just returning two array references. Either way would work the same from outside the sub, though.
      sub f { @foo = ( 1, 2 ); @bar = ( 3, 4 ); @all = ( \@foo, \@bar ); return @all; } foreach ( f() ) { print @{$_}; }
      isn't much different from returning two references:
      sub f { @foo = ( 1, 2 ); @bar = ( 3, 4 ); return \@foo, \@bar; } foreach ( f() ) { print @{$_}; }
        I am sure this will be subject to debate, but I have learned that it is more efficent to return a reference then the whole thing.

        For example, if you array is a million elements and you a million arrays, then that is alot to pass around. The size of that versus the size of one scalar (the reference) is obviously very different. Because of this, I have gotten in the habit of returning references to data structures, especially complex ones such as arrays or arrays.

        I believe that
        @all = (\@foo, \@bar); return @all;
        and
        return \@foo, \@bar;
        are identical so far as perl is concerned. Kind of like
        print (1, 2, 3, 4); # and print 1, 2, 3, 4;

        Anyway my suggestion is that if you're expecting a set number of elements from a subroutine then you can do something like this:

        my ($aryref1, $aryref2) = subroutine(); # or if you want the longer way. my $aryref1; my $aryref2; ($aryref1, $aryref2) = subroutine();
        Note that if a subroutine returns a list and you do something like:
        my $ret = subroutine();
        Then $ret will be the number of elements in the list that subroutine returned, not the first.

        Jacinta