参数传递给Perl子例程的顺序是否显着?当我调试以下代码时:
my $loopCounter = 1;
foreach(@authors) {
my @splitAffiliations = splitAffiliations($params);
my @foundItems = findAffiliationForAuthor($_, @splitAffiliations, $loopCounter);
# Process @foundItems
$loopCounter++;
}
...
sub findAffiliationForAuthor {
my ($author, @affiliations, $aIndex) = @_;
...
}
我发现变量$loopCounter
在调用子例程findAffiliationForAuthor
之前有一个值,但在调用后未定义。因此,子程序接收前两个参数的值而第三个参数没有任何值。但是,当我将参数的顺序更改为:
my @foundItems = findAffiliationForAuthor($loopCounter, $_, @splitAffiliations);
保留$loopCounter
的值并按预期传递子例程。
看起来我必须将所有标量变量放在我的数组变量之前,或者可能不会混合它们。听起来不错吗?
答案 0 :(得分:5)
当然,订单很重要。
参数按照传递它们的顺序传递,数组参数展平到参数列表中。参数列表在子例程内显示为@_
列表的内容。
你实际上不能将数组作为参数传递;它的元素被提取并用任何其他参数推入列表中。
您遇到的问题是因为您处理参数的方式:
my ($author, @affiliations, $aIndex) = @_;
$author
按照您的意图获取@_
的第一个元素,但@affiliations
会覆盖列表的其余部分。然后将值undef
存储在$aIndex
。
只要它是最后一个参数,您就可以将单个数组传递给子例程:
my($first_scalar, $second_scalar, @array) = @_;
如果将多个数组传递给子例程:
foo(@array1, @array2);
两个数组的元素被展平为一个列表,子程序无法知道哪个元素来自哪个数组参数。
您可以将引用传递给数组:
sub foo {
my ($scalar1, $array_ref1, $scalar2, $array_ref2) = @_;
# ...
}
然后像这样调用它:
foo(42, \@array1, $some_scalar, \@array2);
答案 1 :(得分:2)
子例程将标量列表作为参数。如果从数组构建参数列表,则将传递数组的内容。
$ perl -E'sub f { say "$_: $_[$_]" for 0..$#_; } f("a", "b", "c", "d", "e")'
0: a
1: b
2: c
3: d
4: e
$ perl -E'sub f { say "$_: $_[$_]" for 0..$#_; } @a = ("b"); f("a", @a, "c", "d", "e")'
0: a
1: b
2: c
3: d
4: e
$ perl -E'sub f { say "$_: $_[$_]" for 0..$#_; } @a = ("b", "c"); f("a", @a, "d", "e")'
0: a
1: b
2: c
3: d
4: e
现在您将参数列表(@_
的内容)分配给
($author, @affiliations, $aIndex)
它应该为@affiliations
分配多少个标量?你可以说除了第一个和最后一个之外的所有内容,但是你必须为
my (@a, @b) = @_;
为了简单起见,Perl总是将所有剩余的标量分配给列表中的第一个数组。如果数组是最后一个元素,则可以正常工作,但不是这样。
如果要将数组传递给sub,最好的方法是传递对它的引用。
$ perl -E'sub f { say "$_: $_[$_]" for 0..$#_; } @a = ("b", "c"); f("a", \@a, "d", "e")'
0: a
1: ARRAY(0x14ff8d0)
2: d
3: e