Forum Moderators: coopster & phranque

Message Too Old, No Replies

Arrays with Perl

         

jean_dave80

5:03 am on Apr 28, 2003 (gmt 0)

10+ Year Member



Hi all,

I am trying to send an array as a parameter in one of my functions in Perl.

e.g

my @array = ("dog", "cat", "mouse", 234, "my uncle Bill");
&sendArray(@array);

sub sendArray {

my @sub_array = shift;
print @sub_array;
}
~~~~~~~ ¦¦ ~~~~~~
This will only print the first element of the array. Any help will be very appreciated.

cheers.

ShawnR

5:32 am on Apr 28, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi Jean_Dave & welcome to WebmasterWorld!

sub sendArray {
my @sub_array = @_;

# now $sub_array[0] is 'dog',
# $sub_array[1] is 'cat',
# etc

}

Shawn

andreasfriedrich

11:38 am on Apr 28, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Perl [perl.com] flattens all parameter of a function into a list. This list may be accessed from within the function via the @_ array. shift [perldoc.com] may be used to access the first element of that array. Assigning @_ to a local array will make a copy of it and store it in that local array variable.

Note that because of this behaviour it is not possible to pass an array as the first argument and a scalar value or second array as a second argument of a function call.


@names = q [perldoc.com]w(aaron nick stevie);
$name = 'jesse';
my_function(@names, $name);
sub my_function {
(@lnames, $lname) = @_;
print [perldoc.com] "\@lnames: ", join [perldoc.com](' ', @lnames), "\n";
print [perldoc.com] "\$lname: $lname\n";
}

will print


@lnames: aaron nick stevie jesse
$lname:

All arguments were flattened into a list and copied to @lnames. To pass multiple arrays you need to pass a reference to the array.


@names = q [perldoc.com]w(aaron nick stevie);
$name = 'jesse';
my_function(\@names, $name);
sub my_function {
($lnames_ref, $lname) = @_;
print [perldoc.com] "\@names: ", join [perldoc.com](' ', @$lnames_ref), "\n";
print [perldoc.com] "\$lname: $lname\n";
}

will output


@lnames: aaron nick stevie
$lname: jesse

Andreas

jean_dave80

3:57 am on Apr 29, 2003 (gmt 0)

10+ Year Member



But, if we have to send two arrays at a time...

let's say I have a function returning two arrays

(@first, @second) = &my_subroutine($i);

sub my_subroutine{
my $scalar = shift;

###do something....

return (@array1, @array2);
}

-----------------------------------------------
This will flatten @array1 and @array2 in @first!

Any idea how to get around this?

Thanks

[edited by: jean_dave80 at 5:21 am (utc) on April 29, 2003]

ShawnR

5:02 am on Apr 29, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



That's right. And you can't return references to the arrays, as the arrays won't be there to deref after the function ends. 2 options I can see:
  1. return the size of your arrays, then your arrays, or
  2. have the arrays declared outside your function, and have your function set them as a side-effect, rather than return them (not too elegant). You could call your function with the references to those arrays (and obviously comment it) so that anyone looking at your code later will see that the function has a side effect.

Shawn

andreasfriedrich

11:51 am on Apr 29, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member




>>you can't return references to the arrays, as the arrays
>>won't be there to deref after the function ends

Not. The arrays will stick around until there is no longer any reference pointing to them. So if you return a reference to some arrays you can still dereference them in your main script although the actual arrays have gone out of scope.


sub test {
my @a1 = qw(aaron nick);
my @a2 = qw(taylor zac);
return (\@a1, \@a2);
}
#
(my $a1, my $a2) = test();
#
print join(' and ', @$a1), "\n", join(' and ', @$a2);

will print


aaron and nick
taylor and zac

Andreas

ShawnR

12:24 pm on Apr 29, 2003 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



OK, thanks. Sorry for the misinformed post (I thought I had tried it once...). If they persist then that makes for a much neater solution.