SLP
SLP

Reputation: 305

Perl - function with two array arguments

I have troubles using a function in Perl.

My function has 2 arguments which are arrays :

sub get_coordinate {
    my (@array_col, @array_lin) = (@_);

    do some stuff
}

I call it this way :

    $index_col                  = int(rand(10));
    $index_lin                  = int(rand(10));
    @array_col                  = (0,0,0,0,0,0,0,0,0,0);
    @array_lin                  = (0,0,0,0,0,0,0,0,0,0);
    $array_col[$index_col]      = 1;
    $array_lin[$index_lin]      = 1;

    get_coordinate(@array_col, @array_lin);

My problem is that I get the error message : Use of uninitialized value within @array_lin in numeric eq (==) at switch.pl line 82 (#1) (W uninitialized) An undefined value was used as if it were already defined. It was interpreted as a "" or a 0, but maybe it was a mistake. To suppress this warning assign a defined value to your variables.

I don't understand why @array_col is initialized an not @array_lin.

When I print @array_col and @array_lin inside the function this way :

print "@array_col\n@array_lin\n";

I get : 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0

Any idea ?

Thx, SLP

Upvotes: 2

Views: 116

Answers (2)

simbabque
simbabque

Reputation: 54323

In Perl, all lists are flat. These two lists are equivalent.

( 1, 2, ( 3, 4, ( 5 ), (6, 7), 8), (), )
( 1, 2, 3, 4, 5, 6, 7, 8 )

The same thing also happens when take several arrays and stick them in a list.

my @foo = (1, 2, 3);
my @bar = (4, 5, 6);
my @new = (@foo, @bar); # 1, 2, 3, 4, 5, 6

When you pass things to a function, those things get turned into a list of arguments. Therefore, the arrays will both end up in one list, like @foo and @bar above.

frobnicate(@foo, @bar);

When you assign something in list context, the entire list will be assigned left to right. For scalars in the list on the left-hand-side this means they will get their values. But as soon as there is an array, this will be greedy. It will suck up all the remaining values.

my ($one, $two, @rest, $will_be_undef) = (1, 2, 3, 4, 5, 6);

The values will be assigned like this:

$one = 1;
$two = 2;
@rest = ( 3, 4, 5, 6 );
$will_be_undef = undef;

What you need to do to pass two arrays is to take references, and dereference them in our function.

frobnicate( \@foo, \@bar );

sub frobnicate {
    my ($first_array, $second_array) = @_;

    my @foo = @{ $first_array };
    my @bar = @{ $second_array };

    ...
}

Upvotes: 8

choroba
choroba

Reputation: 241808

Assigning to several arrays (or hashes) doesn't do what you think:

my (@array1, @array2) = ...

The first array gets all the elements. How should it know where to stop?

You can use array references instead:

sub get_coordinate {
    my ($arr1, $arr2) = @_;
    my @arr1 = @$arr1;
    my @arr2 = @$arr2;
    ...
}
get_coordinate(\@array1, \@array2);

Upvotes: 2

Related Questions