2016-07-25 110 views
1

尝试这样的:perl的名单:: AllUtils uniq的和排序

perl -Mv5.14 -MList::AllUtils=uniq -E 'my(@x) = qw(2 3 1 2); say "@x"; my(@y) = uniq @x; say "@y"' 

它正确打印

2 3 1 2 
2 3 1 

现在要有序输出,所以尝试:

perl -Mv5.14 -MList::AllUtils=uniq -E 'my(@x) = qw(2 3 1 2); say "@x"; my(@y) = sort uniq @x; say "@y"' 

令人惊讶的是打印:

2 3 1 2 
2 1 3 2 

切换uniq的顺序和sort

perl -Mv5.14 -MList::AllUtils=uniq -E 'my(@x) = qw(2 3 1 2); say "@x"; my(@y) = uniq sort @x; say "@y"' 

给出正确的结果

2 3 1 2 
1 2 3 

因此,使用MO=Deparse进行比较。

第1:

perl -MO=Deparse -Mv5.14 -MList::AllUtils=uniq -E 'my(@x) = qw(2 3 1 2); say "@x"; my(@y) = uniq @x; say "@y"' 
sub BEGIN { 
    require v5.14; 
} 
use List::AllUtils (split(/,/u, 'uniq', 0)); 
use strict; 
use feature 'current_sub', 'evalbytes', 'fc', 'postderef_qq', 'say', 'state', 'switch', 'unicode_strings', 'unicode_eval'; 
my(@x) = ('2', '3', '1', '2'); 
say join($", @x); 
my(@y) = &uniq(@x); 
say join($", @y); 
-e syntax OK 

第二:

perl -MO=Deparse -Mv5.14 -MList::AllUtils=uniq -E 'my(@x) = qw(2 3 1 2); say "@x"; my(@y) = sort uniq @x; say "@y"' 
sub BEGIN { 
    require v5.14; 
} 
use List::AllUtils (split(/,/u, 'uniq', 0)); 
use strict; 
use feature 'current_sub', 'evalbytes', 'fc', 'postderef_qq', 'say', 'state', 'switch', 'unicode_strings', 'unicode_eval'; 
my(@x) = ('2', '3', '1', '2'); 
say join($", @x); 
my(@y) = (sort uniq @x); 
say join($", @y); 
-e syntax OK 

第三:

perl -MO=Deparse -Mv5.14 -MList::AllUtils=uniq -E 'my(@x) = qw(2 3 1 2); say "@x"; my(@y) = uniq sort @x; say "@y"' 
sub BEGIN { 
    require v5.14; 
} 
use List::AllUtils (split(/,/u, 'uniq', 0)); 
use strict; 
use feature 'current_sub', 'evalbytes', 'fc', 'postderef_qq', 'say', 'state', 'switch', 'unicode_strings', 'unicode_eval'; 
my(@x) = ('2', '3', '1', '2'); 
say join($", @x); 
my(@y) = &uniq(sort(@x)); 
say join($", @y); 
-e syntax OK 

的区别是uniq子程序是如何调用:

my(@y) = (sort uniq @x); # sort uniq @x 
my(@y) = &uniq(sort(@x)); # uniq sort @x 

我的理解比uniq是由List::AllUtils提供的子程序和sort是内置的功能,但使用uniq为:

my(@y) = &uniq(sort(@x)); 

似乎并不对我来说非常intutive。

我必须在&uniq(...)表格中使用它,例如,与&和括号? Coudl有人请添加一些关于?

回答

2

如果你运行它use strictuse warnings它告诉你什么是错的。

use strict; 
use warnings; 
use feature 'say'; 
use List::AllUtils 'uniq'; 

my (@x) = qw(2 3 1 2); 
say "@x"; 
my (@y) = sort uniq @x; 
say "@y"; 

这给了警告排序子程序没有在返回一个值。 sort认为uniq是它应该用来排序列表的子例程。

The sort documentation解释了这一点。

排序SUBNAME LIST
排序块列表
排序列表

你也可以给它一个子的名字。直接使用该子名称(即,不是作为字符串,或作为代码引用)有点违反直觉,但这就是它应该是的。文档中甚至有一个例子。

# sort using explicit subroutine name 
sub byage { 
    $age{$a} <=> $age{$b}; # presuming numeric 
} 
my @sortedclass = sort byage @class; 

所以在这种情况下,它把你的uniq不是_call uniq(@x)和排序使用默认sort行为的返回值,而是它确实排序@x使用uniq作为排序功能


您可以sort忽略子名称和前面加上一个+标志使用返回值来代替。

my (@x) = qw(2 3 1 2); 
say "@x"; 
my (@y) = sort +uniq @x; 
say "@y"; 

__END__ 
2 3 1 2 
1 2 3 

现在没有警告。 sort +uniq(@x)也有效,并且更易于阅读。

+0

使用-Mv5.14启用'strict',甚至您的示例中的'warnings'也不会显示任何警告。至少对我来说 - 使用'v5.24.0'。 – kobame

+0

@ kobame嗯,这很奇怪。我有5.20。但那仍然是发生的事情。警告或不警告。你可以通过给它一个子名 – simbabque

+1

'sort(uniq(@x))'覆盖缺省行为,只要'uniq'后面没有空格就行了 – Borodin