perl的名单:: AllUtils uniq的和排序
问题描述:
尝试这样的: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有人请添加一些关于?
答
如果你运行它use strict
和use 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)
也有效,并且更易于阅读。
使用-Mv5.14启用'strict',甚至您的示例中的'warnings'也不会显示任何警告。至少对我来说 - 使用'v5.24.0'。 – kobame
@ kobame嗯,这很奇怪。我有5.20。但那仍然是发生的事情。警告或不警告。你可以通过给它一个子名 – simbabque
'sort(uniq(@x))'覆盖缺省行为,只要'uniq'后面没有空格就行了 – Borodin