When the arguments are to be captured in a combination of array and scalar variables, special care has to be taken. In this case, only one array is allowed, and it has to be the last variable in the list to which @_ is assigned.
Compare the two programs below:
#!/usr/local/bin/perl
$a = 1;
$b = 2;
@list = (10, 20, 30);
good ($a, $b, @list); # function invocation
sub good {
my ($first, $second, @group) = @_; # capturing arguments
print "first: $first\n",
"second: $second\n",
"group: @group\n";
}
# program output: first: 1
# second: 2
# group: 10 20 30
Upon function invocation, @_ contained (1, 2, 10, 20, 30).
When it was assigned to ($first, $second, @group), $first got 1,
$second got 2 and @group then captured the rest (i.e. 10, 20, 30).
That's what we wanted.
#!/usr/local/bin/perl
$a = 1;
$b = 2;
@list = (10, 20, 30);
bad (@list, $a, $b); # function invocation. array is first.
sub bad {
my (@group, $first, $second) = @_; # will produce
# unexpected results!
print "group: @group\n",
"first: $first\n",
"second: $second\n";
}
# program output: group: 10 20 30 1 2 # mmm...
# first:
# second:
Upon function invocation, @_ contained (10, 20, 30, 1, 2).
When it was assigned to (@group, $first, $second),
@group captured "the rest", i.e. all, and nothing was left
for $first and $second.
This problem can be avoided when arrays are passed into functions by reference, which is also a good practice when dealing with large arrays or when passing more than one array. For more details, see pages 116-118 and chapter 4 ("References and Nested Data Structures") in the "Programming Perl" book.