2014-09-30 79 views
10

我明白如何从使用Perl的sort()函数得到我想要的结果,这更多的是关于sort()的内部工作的问题。

“$ a”和“$ b”变量来自哪里?我通读文件进行排序,似乎不清楚。什么是“$ a”和“$ b”,是什么使它们变得特别?

例如:

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

怎么样知道做什么用“$ a”和“$ b”和做你为什么不得到“全局符号需要明确包名”错误“$一个“或”$ b“?

+6

来自'perldoc strict':'因为它们按sort()的特殊用法,所以变量$ a和$ b可以免于此检查。“ – toolic 2014-09-30 18:32:51

+0

$ a和$ b是红色框中的元素。 http://en.wikipedia.org/wiki/Merge_sort#mediaviewer/File:Merge-sort-example-300px.gif – 2014-09-30 18:48:12

回答

17

$a$b免征全局变量;它们免除了Perl允许它们在不被声明的情况下被使用(任何地方)。它们由排序功能设置。使用其他未声明的全局(严格模式)会触发错误。

排序函数接受各种形式的输入,其中一个是代码块,它是您所指的形式。

{$a cmp $b}是一个码块时,它被解析并作为“的代码块”来排序函数传递和Perl检查参数为排序,如果它接收到一个代码块,排序将设置$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实际上是您当前包中的全局变量,而不是在排序函数中的一些魔术$a,尽管Perl知道允许您在严格模式下定义它们。

您不能只使用任何变量(在严格模式下)。尝试:

sort {$A cmp $B} @list; 

Global symbol "$A" requires explicit package name at sort.pl 

您不能在排序范围中使用词法(my $ a)。

my $a; 
sort {$a cmp $b} @list; 

Can't use "my $a" in sort comparison at sort.pl line 13. 

$a$b特殊Perl中的任何地方。他们免于严格模式,这与排序无关,但sort是豁免的原因。

+0

一个非常好的答案。我希望我可以两次上调它。 – LeoNerd 2014-10-01 14:24:34

5

Perl的“sort()”函数的比较代码中的“$ a”和“$ b”究竟是什么?

从值列表中排序的两个值。该块将返回关于在最终结果中如何定位到另一个的信息。

什么是“$ a”和“$ b”,什么使它们变得特别?

包变量,除了use strict 'vars';不考虑使用它们是一个错误。

“$ a”和“$ b”变量来自哪里?

它们由sort填充。

怎么样知道做什么用“$ a”和“$ B”

它不与他们做任何东西,除了按要求完成其功能填充他们做。

为什么“$ a”或“$ b”出现“Global symbol requires explicit package name”错误?

这将使它很难使用它们!

如果你定义一个局部变量,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. 
+0

所以你所说的是“$ a”和“$ b”是专门为使用'sort()'函数并没有其他函数?如果你定义了一个局部变量'my $ a'或'my $ b',会发生什么情况,然后尝试在可见的局部变量范围内使用排序? – tjwrona1992 2014-09-30 19:15:46

+1

@ tjwrona1992给它一个去看看会发生什么! – 2014-09-30 19:16:53

+0

@ tjwrona1992 - 查看我答案的底部。你不能使用词汇(但为什么不自己试试看?) – codenheim 2014-09-30 19:20:08

2

其他答案是好的,所以我不会重复,但你的问题的一部分并没有真正回答。

“$ a”和“$ b”变量来自哪里?

由于codenheim写道:sort基本上一直延伸到你的模块(不管它是一个明确的模块或模块main),并确定在你的范围的变量。怎么样?只需暂时关闭strict refs并拼写出完全限定的变量名称即可。完成后,变量可以通过${$variable_name}访问。

my $pkgname = caller(); 
my $varname = "${pkgname}::a"; 
no strict 'refs'; 
${$varname} = value; 

注:我发现在source这种技术List::Util