到底是什么" $ a"和" $ b"在Perl" sort()"功能?

时间:2014-09-30 18:26:35

标签: perl sorting scope

我理解如何使用Perl的sort()函数获得我想要的结果,这更像是sort()的内部工作方式的问题。

“$ a”和“$ b”变量来自哪里?我阅读了文档中的排序,似乎不清楚。什么是“$ a”和“$ b”以及它们的特殊之处是什么?

例如:

my @sorted_list = sort {$a cmp $b} @unsorted_list;

如何排序知道如何处理“$ a”和“$ b”以及为什么不为“$ a”或“$ b”获得“全局符号需要显式包名称”错误?

3 个答案:

答案 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 $amy $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;

注意:我在sourceList::Util中发现了这种技术。