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

I would like to return 3 arrays from a subroutine. And automatically assign it to 3 arrays when calling the subroutine. e.g sub foo { .... .... return 3 arrays @a1 @a2 @a3 } then I should be able to do something like my (@array1, @array2, @array3) = foo(); and @array1 should contain @a1, @array2 contains @a2 and so on.

Replies are listed 'Best First'.
Re: Returning multiple arrays
by dragonchild (Archbishop) on Feb 17, 2005 at 14:29 UTC
    You need to use array references. perlreftut is a good place to start.

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

      Please go through References for more information.

      --Binoj
Re: Returning multiple arrays
by trammell (Priest) on Feb 17, 2005 at 14:30 UTC
    Found in perldoc perlsub:
      Where people get into trouble is here:
    
           (@a, @b) = func(@c, @d);
      or
           (%a, %b) = func(%c, %d);
    
      That syntax simply won't work.  It sets just @a or %a
      and clears the @b or %b.  Plus the function didn't get
      passed into two separate arrays or hashes: it got one
      long list in @_, as always.
    
Re: Returning multiple arrays
by sh1tn (Priest) on Feb 17, 2005 at 15:30 UTC
    Quick example:
    @a = a..d; @b = e..h; ($c, $d) = _ret_arr(\@a, \@b); #print "@$c \t @$d $/"; #print "@a \t @b $/"; sub _ret_arr { my $a = shift; my $b = shift; my (@tmp_a, @tmp_b) = (@$a, @$b); # by reference #map{ $_ = uc }@$a,@$b; #return $a, $b; # by values #map { $_ = uc } @tmp_a, @tmp_b; #return \@tmp_a, \@$tmp_b }

    Still perlref document is far more useful!


Re: Returning multiple arrays
by manojrajgarhia (Initiate) on Feb 17, 2005 at 15:18 UTC
    Hope this helps

    Regards
    Manoj
    #!/usr/bin/perl use warnings; use strict; my ($a, $array_a , $array_b) = p_sub_a( ) ; print @$array_a[0]; print @$array_a[1]; print @$array_b[0]; print @$array_b[1]; exit 0; sub p_sub_a { my $a; my @array_aa ; my @array_bb; $array_aa[0] = "1\n"; $array_aa[1] = "2\n"; $array_bb[0] = "1b\n"; $array_bb[1] = "2b\n"; return ($a, \@array_aa , \@array_bb); }

    Code tags added by davido.

      There's a subtile mistake in your code. You're improperly dereferencing $array_a and $array_b. Yes, it's working for you ok, but consider the following code:

      perl -we "@array = qw/one two three/; print @array[1], $/;"

      And the warning is...

      Scalar value @array[1] better written as $array[1] at -e line 1.

      Why? Because @array[1] is an array slice of exactly one element. It's similar to @array[0 .. 3], except for being just one element. Perl prefers (for various good reasons) that you use slice semantics when you intend a slice, and scalar semantics when you mean a single element of an array.

      Now, why doesn't your example throw a warning? Because you're dealing with references, not simple arrays. I suppose nobody's thought to add such a warning to Perl's repertoire yet, but it probably ought to be there.

      The proper way to dereference $array_a would be like this:

      print $array_a->[0];

      Hope this clears up a potential future mistake... ;)


      Dave