我有一个脚本和包这样:
# file: sortscript.pl
use strict;
use warnings;
use SortPackage;
my @arrays = ([1,"array1"],[10,"array3"],[4,"array2"]);
print "Using sort outside package\n";
foreach (sort SortPackage::simplesort @arrays){
print $_->[1],"\n";
}
print "\nUsing sort in same package\n";
SortPackage::sort_from_same_package(@arrays);
-
# file: SortPackage.pm
use strict;
use warnings;
package SortPackage;
sub simplesort{
return ($a->[0] <=> $b->[0]);
}
sub sort_from_same_package{
my @arrs = @_;
foreach (sort simplesort @arrs){
print $_->[1],"\n";
}
}
1;
运行脚本会产生输出:
$ perl sortscript.pl
Using sort outside package
Use of uninitialized value in numeric comparison (<=>) at SortPackage.pm line 15.
Use of uninitialized value in numeric comparison (<=>) at SortPackage.pm line 15.
Use of uninitialized value in numeric comparison (<=>) at SortPackage.pm line 15.
Use of uninitialized value in numeric comparison (<=>) at SortPackage.pm line 15.
Use of uninitialized value in numeric comparison (<=>) at SortPackage.pm line 15.
Use of uninitialized value in numeric comparison (<=>) at SortPackage.pm line 15.
array1
array3
array2
Using sort in same package
array1
array2
array3
为什么我无法正确使用子程序在另一个包中进行排序?
答案 0 :(得分:6)
如前所述,$a
和$b
是包全局变量,因此另一种解决方案是将调用站点的全局变量临时别名为包SortPackage
中的全局变量:
{
local (*a, *b) = (*SortPackage::a, *SortPackage::b);
foreach (sort SortPackage::simplesort @arrays){
print $_->[1],"\n";
}
}
但当然,这非常难看。我只需要SortPackage
导出一个完整的排序例程,而不仅仅是比较器:
package SortPackage;
use strict;
sub _sort_by_first_element_comparator {
return $a->[0] <=> $b->[0];
}
sub sort_by_first_element {
return sort _sort_by_first_element_comparator @_;
}
答案 1 :(得分:5)
$a
和$b
是特殊的“包全局”变量。
要使用主范围的$a
和$b
,您的比较器功能必须引用$::a
或$main::a
(同样适用于$b
)。< / p>
然而,当从任何其他包中调用时, 时,将不会工作。或者甚至在其自己的包中。
请参阅perlvars
帮助和perldoc
sort
功能。解决方案也在后一个帮助文本中:
如果子例程的原型是
"($$)"
,那么元素就是 比较在@_
中通过引用传递,与法线相同 子程序。这比非原型子程序慢, 将要比较的元素传递给 子程序作为包全局变量$a
和$b
(参见 例子如下)。请注意,在后一种情况下,通常是这样 将$a
和$b
声明为词汇,会产生反作用。
答案 2 :(得分:5)
特殊变量$a
和$b
是包全局变量。您的子例程需要$SortPackage::a
和$SortPackage::b
。当您从sortscript.pl
拨打电话时,变量$main::a
和$main::b
由sort
设置。
解决方案是使用原型子程序:
package SortPackage;
sub simplesort ($$) {
return ($_[0]->[0] <=> $_[1]->[0]);
}
它有点慢(因为你传递了实际的参数,而不是读取预设的全局变量),但它允许你在尝试时按名称使用其他包中的子程序。