我理解如何使用Perl的sort()
函数获得我想要的结果,这更像是sort()
的内部工作方式的问题。
“$ a”和“$ b”变量来自哪里?我阅读了文档中的排序,似乎不清楚。什么是“$ a”和“$ b”以及它们的特殊之处是什么?
例如:
my @sorted_list = sort {$a cmp $b} @unsorted_list;
如何排序知道如何处理“$ a”和“$ b”以及为什么不为“$ a”或“$ b”获得“全局符号需要显式包名称”错误?
答案 0 :(得分:19)
$a
和$b
是免除全局变量;它们是免除的,因为Perl允许它们被使用(任何地方)而不被声明。它们由sort函数设置。在排序中使用任何其他未声明的全局(在严格模式下)将触发错误。
sort函数接受各种形式的输入,一个是代码块,这是你所指的形式。
{$a cmp $b}
是一个代码块,它被解析并作为"代码块传递#34;对于sort函数,Perl检查参数是否有排序,如果它接收到代码块,sort将设置$a
和$b
,如果它们作为代码块中的包全局变量存在,则为每个对分配项目排序为$a
和$b
。您所要做的就是参考它们来控制排序算法。否则,使用内部算法(我认为是合并排序)。
http://perldoc.perl.org/functions/sort.html
$a
和$b
不是词法,它们是包全局变量(或者只是全局变量)。
在主要内容中你可以写:
sort {$main::a cmp $main::b} @list;
或者在另一个包中,你可以写:
package foo;
sort {$foo::a cmp $foo::b} @list;
你不应该像这样加前缀;我正在证明$a
和$b
实际上是当前包中的全局变量,而不是sort函数中的一些魔术$a
,尽管Perl知道允许你甚至在严格模式下定义它们
您不能只使用任何变量(在严格模式下)。尝试:
sort {$A cmp $B} @list;
Global symbol "$A" requires explicit package name at sort.pl
你不能在排序范围内使用词法(我的$ a)。
my $a;
sort {$a cmp $b} @list;
Can't use "my $a" in sort comparison at sort.pl line 13.
在Perl中, $a
和$b
在任何位置都是特殊的。它们不受严格模式的限制,这与排序无关,尽管sort
是免除的原因。
答案 1 :(得分:5)
Perl的“sort()”函数的[比较代码]中究竟是什么“$ a”和“$ b”?
要排序的值列表中的两个值。该块将返回有关如何在最终结果中将其定位到另一个的信息。
什么是“$ a”和“$ b”以及它们的特殊之处是什么?
包变量,除了use strict 'vars';
不考虑将它们用作错误外,没有什么特别之处。
“$ a”和“$ b”变量来自哪里?
它们由sort
填充。
排序如何知道如何处理“$ a”和“$ b”
除了根据需要填充它们以执行其功能外,它不会对它们执行任何操作。
为什么不为“$ a”或“$ b”获取“全局符号需要显式包名称”错误?
这会让它变得难以使用!
如果定义局部变量
my $a
或my $b
,然后在这些[词汇]变量可见的范围内尝试使用sort
,会发生什么?
如果您的比较函数在my $a
和/或my $b
的范围内,它将使用这些变量而不是包变量sort
填充。
Perl意识到你可能很容易犯错,所以它会检查它。
$ perl -c -e'sort { my ($a,$b); $a cmp $b } @a;'
Can't use "my $a" in sort comparison at -e line 1.
答案 2 :(得分:2)
其他答案都很好,所以我不再重复,但你的问题的一部分没有真正回答。
“$ a”和“$ b”变量来自哪里?
正如科登海姆所写,sort
基本上是深入到你的模块(无论是显式模块还是main
模块)并定义范围内的变量。怎么样?只需暂时关闭strict refs
并拼写出完全限定的变量名称即可。完成后,可以通过${$variable_name}
访问变量。
my $pkgname = caller();
my $varname = "${pkgname}::a";
no strict 'refs';
${$varname} = value;
注意:我在source的List::Util中发现了这种技术。