почему сортировка с uniq не работает вместе

у меня есть следующий скрипт:

use strict;
use List::MoreUtils qw/uniq/;
use Data::Dumper;

my @x = (3,2);
my @y = (4,3);

print "unique results n";
print Dumper([uniq(@x,@y)]);

print "sorted unique resultsn";
print Dumper([sort uniq(@x,@y)]);

выход

unique results 
$VAR1 = [
          3,
          2,
          4
        ];
sorted unique results
$VAR1 = [
          2,
          3,
          3,
          4
        ];

таким образом, похоже, что сортировка не работает с uniq. Я не понимал почему.

я запустил скрипт perl с -MO=Deparse и получил

use List::MoreUtils ('uniq');
use Data::Dumper;
use strict 'refs';
my(@x) = (3, 2);
my(@y) = (4, 3);
print "unique results n";
print Dumper([uniq(@x, @y)]);
print "sorted unique resultsn";
print Dumper([(sort uniq @x, @y)]);

моя интерпретация заключается в том, что perl решил удалить скобки из uniq(@x,@y) и использовать uniq в качестве функции сортировки.

почему perl решил это сделать?

как я могу избежать этих и подобных подводные камни?

спасибо, Дэвид!--4-->

2 ответов


на sort builtin принимает имя подпрограммы или блок в качестве первого аргумента, который передается два элемента. Затем он должен вернуть номер, который определяет порядок между элементами. Все эти фрагменты делают то же самое:

use feature 'say';
my @letters = qw/a c a d b/;

say "== 1 ==";
say for sort @letters;

say "== 2 ==";
say for sort { $a cmp $b } @letters;

say "== 3 ==";
sub func1 { $a cmp $b }
say for sort func1 @letters;

say "== 4 ==";
sub func2 ($$) { $_[0] cmp $_[1] }  # special case for $$ prototype
say for sort func2 @letters;

обратите внимание, что между именем функции и списком нет запятой, и обратите внимание, что parens в Perl используются для определения приоритета – sort func1 @letters и sort func1 (@letters) одинаковы, и ни один из них не выполняется func1(@letters).

чтобы устранить неоднозначность, поместите + перед именем функции:

sort +uniq @letters;

чтобы избежать такого неожиданного поведения, лучшим решением является чтение документов, когда вы не уверены, как ведет себя определенная сборка – к сожалению, у многих есть специальные правила синтаксического анализа.


вы можете поставить скобки вокруг uniq fonction:

print Dumper([sort (uniq(@x,@y))]);

выход:

$VAR1 = [
          2,
          3,
          4
        ];