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

How are arrays (multiple) passed to a subroutine? I am a rank novice and hence seeking ur help . please elobrately explain with examples. Thanks Mudis

Replies are listed 'Best First'.
Re: passing arrays to asubroutine
by emilford (Friar) on Oct 26, 2002 at 12:15 UTC
    You can pass references to the arrays to your subroutine. Try something like this:
    #!/usr/bin/perl -w use strict; # define some arrays my @array1 = qw/apple orange/; my @array2 = qw/pear strawberry/; # call the subroutine passing references to arrays &showFruits(\@array1, \@array2); sub showFruits { # get the array references my ($array1_ref, $array2_ref) = @_; # use the array references to get to arrays foreach my $f1 (@$array1_ref) { print "$f1\n"; } foreach my $f2 (@$array2_ref) { print "$f2\n"; } }
    Hope this helps,
    Eric
      nice, simple and neat !! Anandatirtha
Re: passing arrays to asubroutine
by BrowserUk (Patriarch) on Oct 26, 2002 at 12:20 UTC

    There are two ways to pass arrays to subs. In the first you pass the elements of the array individually.

    sub printArray { for my $element ( @_ ) { print $element, "\n"; } } .... my @array = (1 ,2 ,3 4, 5); printArray( @array );

    Will print the numbers 1 to 5. However, this method doesn't work very well if you want to pass two or more arrays and keep the elements seperate.

    To do this, you need to pass references to the arrays to the sub and then dereference them in the sub to get acces to the elements.

    #! perl -sw use strict; sub printArrays { my ($arrayRef1, $arrayRef2) = @_; for my $element ( @{$arrayRef1} ) { print 'Array1 element: ', $element, "\n"; } for my $element ( @$arrayRef2 ) { print 'Array2 element: ', $element, "\n"; } #another way showing a few more things. for ( my $i=0; $i <= $#{$arrayRef1}; $i++ ) { print "Array1[$i] = ", $$arrayRef1[$i], "\n"; } } my @ary1 = (1, 2, 3, 4, 5); my @ary2 = ('a', 'b', 'c', 'd', 'e'); printArrays( \@ary1, \@ary2 );

    This prgram produces the following output

    c:\test>test Array1 element: 1 Array1 element: 2 Array1 element: 3 Array1 element: 4 Array1 element: 5 Array2 element: a Array2 element: b Array2 element: c Array2 element: d Array2 element: e Array1[0] = 1 Array1[1] = 2 Array1[2] = 3 Array1[3] = 4 Array1[4] = 5 c:\test>

    Hopefully this will get you started. To understand more, read perlsub, then if you are interested in learning more, perlref and perlreftut

    Have fun.


    Cor! Like yer ring! ... HALO dammit! ... 'Ave it yer way! Hal-lo, Mister la-de-da. ... Like yer ring!
      This is not for kids to try at home. :^) Not stuff for beginners. Prototypes are rather weird in Perl and usually best avoided.

      They arcanely change context.

      But it does get around the flattened parameter list issue.

      #!/usr/bin/perl -w use strict; my @arr1 = qw/This is line 1/; my @arr2 = qw/The 2nd line/; sub print2arrays(\@@){ local $, = " "; my $a1 = shift; my @a2 = @_; print @$a1, "\n"; print @a2, "\n"; } print2arrays @arr1, @arr2;
Re: passing arrays to asubroutine
by Bilbo (Pilgrim) on Oct 26, 2002 at 12:17 UTC

    You need to pass references to the arrays, rather than the array itself, so the call to your subroutine would look like: subroutine(\@array1, \@array2 ...)

    Your subroutine would then use them like this:

    sub subroutine { my ($array_ref1, $array_ref2) = @_; your code here }

    To access the elements of the array oyu need to dereference it. To access the nth element of the array you can use ${$array_ref1}[n] or equivalently $array_ref1->[n].

    Try looking at perlref for more details

Re: passing arrays to asubroutine
by broquaint (Abbot) on Oct 26, 2002 at 16:28 UTC
    Now that everyone has thoroughly explained the how I shall explain the why.

    Parameters that are passed to a subroutine are evaluated in list context and the resulting list is passed on to the subroutine, and when arrays are evaluated in a list context they are flattened to a list (the same is true of hashes). So when two arrays are passed to a subroutine, they are both evaluated in list context and flattened, resulting in a single list which is then passed onto a subroutine. To get around this we pass a reference to the subroutine instead, and since that is just a scalar it will not change in list context.

    Here's some code to demonstrate the above paragraph

    use strict; sub foo { print "got: ", join(', ', map { ref($_) ? "[@$_]" : $_ } @_),"\n"; } my @alpha = qw( a b c ); my @nums = qw( 1 2 3 ); # flattened array foo(@alpha); # 2 flattened arrays foo(@alpha, @nums); # array ref and flattened array foo(\@alpha, @nums); # flattened array and 2 array refs foo(@nums, \@alpha, [qw/d e f/]); # flattened array, an array ref and a list foo(@nums, [ qw/4 5 6/ ], qw/7 8 9/); __output__ got: a, b, c got: a, b, c, 1, 2, 3 got: [a b c], 1, 2, 3 got: 1, 2, 3, [a b c], [d e f] got: 1, 2, 3, [4 5 6], 7, 8, 9
    So you can see there that the arrays are being flattened, lists are behaving normally and array refs work as expected.
    HTH

    _________
    broquaint

Re: passing arrays to asubroutine
by Anonymous Monk on Oct 26, 2002 at 11:47 UTC
    using the "@_ " variable may be a way of passing variables but @_ variable has scalar elements. As i understand from your requirement you need to pass one or more arrays to a subroutine.. well at this poinit of time , I am not sure how . Monks please enlighten !!! Regards Ananda
      This sounds something like passing variables to functions within a java class file. Sounds Interusting!!! Monks please respond. Regards, Anandatirtha