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

Hello Wise Monks,

Is there a way a subroutine can return 2 individual arrays at the same time.

How can I do the following? (If at all I can do it?)

my @array = &xsubroutine(); my @mainarray1 = shift @array; my @mainarray2 = shift @array; sub xsubroutine{ my (@array1, @array2) yada; yada; psuh (@array1, $_); yada; yada; push(@array2, $_); }

At this point I want the subroutine to Return both the arrays (array1 and array2) to the "main" for furthur use as shown. Can I even do this?

Thank you all for the help.

ALM (A Learning Monk)

Replies are listed 'Best First'.
Re: Returning two arrays..
by tstock (Curate) on Jan 04, 2002 at 09:14 UTC
    You can't return two arrays since functions only return lists, but you can return a list with two (or more) array references. In its most readable format it would look something like this:

    sub mySub { my $array_ref1 = \@array1; my $array_ref2 = \@array2; return ($array_ref1, $array_ref2); } my ($arr_ref1, $arr_ref2) = mySub(); my @array_ref1 = @{$arr_ref1}; my @array_ref2 = @{$arr_ref2};
Re: Returning two arrays..
by impossiblerobot (Deacon) on Jan 04, 2002 at 07:23 UTC
Re: Returning two arrays..
by count0 (Friar) on Jan 04, 2002 at 20:57 UTC
    While impossiblerobot and tstock provided excellent solutions, it may help to understand why these solutions are needed.

    When you return() an array, it is sent back (so to speak) as a list. The variable @array provides a nice little grouping for all its elements. If we had @array = ('a', 'b'); and return()'ed it, the portion catching this value will get ('a', 'b') and that variable container, @array, is no more.

    What does this lead to? Well, given the following:
    sub foo { my @a = qw(a b); my @b = qw(c d); return (@a, @b); }<br> @return_val = foo();
    You might expect @return_val to contain ('a', 'b')... But because the return value is put into a list, ('a', 'b', 'c', 'd') is returned from foo(). There aren't any @a or @b anymore to "draw the line" and distinguish one array from the other... it's just one big list.

    So anyhow, by returning scalars (strings, hash refs, array refs, etc), you always ensure that the elements of each of the return values (or the elements pointed to by them) stay in their container variables. =)
      Your wisdom has enlightened me. However... Given the simplicity,IMHO, why are young monks not taught to play with arrays such:
      #**function to concatenate another value onto the end of each string. #!!Value to be added specified as last scalar sub addvalue($$$); my ($ref1,$ref2); @$ref1=("meet","my"); @$ref2=("say","hello","to","my"); ($ref1,$ref2)=addvalue($ref1,$ref2,"dog"); print "@$ref1\n"; print "@$ref2\n"; sub addvalue($$$) {my ($a,$b,$c); @$a=@{$_[0]}; @$b=@{$_[1]}; $c=$_[2]; push(@$a,$c); push(@$b,$c); return ($a,$b);}
      I am Takophiliac. The evil souls remind me and in the darkness find me.
Re: Returning two arrays..
by metadoktor (Hermit) on Jan 04, 2002 at 16:42 UTC
    One way of returning two (or more) arrays is by trying the following code. Note that in this example I am returning three array references.

    #!/usr/local/bin/perl -w
    
    use strict;
    
    my ($f1,$f2,$f3)=foo();
    
    print "arry1 arry2 arry3\n";
    print "----- ----- -----\n";
    for my $i (0..(scalar(@$f1)-1))
    {
      print " @$f1[$i]    @$f2[$i]    @$f3[$i]\n";
    }
    
    sub foo
    {
      my @$arry1=("a1","a2","a3");
      my @$arry2=("b1","b2","b3");
      my @$arry3=("c1","c2","c3");
    
      return @_=($arry1,$arry2,$arry3);
    }

    Should print out the following:

    arry1 arry2 arry3
    ----- ----- -----
     a1    b1    c1
     a2    b2    c2
     a3    b3    c3
    metadoktor

    "The doktor is in."

      return @_=($arry1,$arry2,$arry3);

      I wonder what the point of that assignment is? What advantages does it have over a simple:

      return $arry1, $arry2, $arry3;
      --
      <http://www.dave.org.uk>

      "The first rule of Perl club is you do not talk about Perl club."
      -- Chip Salzenberg