Why sorting with uniq does not work together

I have the following script:

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 results\n"; print Dumper([sort uniq(@x,@y)]); 

Output signal

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

So it seems that sorting does not work with uniq. I did not understand why.

I ran perl script with -MO = Deparse and got

 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 results\n"; print Dumper([(sort uniq @x, @y)]); 

My interpretation is that perl decided to remove the parentheses from uniq (@x, @y) and use uniq as a sort function.

Why did the pearl decide to do this?

How can I avoid these and similar traps?

Thanks David

+6
source share
2 answers

sort inline takes a name or subroutine block as the first argument, which passes two elements. Then it should return a number that determines the order between the elements. These fragments are all the same:

 use feature 'say'; my @letters = qw/acadb/; 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; 

Note that there is no comma between the function name and the list, and note that the Parens parameters in Perl are used to determine the priority first - sort func1 @letters and sort func1 (@letters) match and sort func1 (@letters) are not executed.

To resolve the ambiguity, put + in front of the function name:

 sort +uniq @letters; 

To avoid this unexpected behavior, the best solution is to read documents when you don’t know how a certain built-in controller behaves - unfortunately, many of them have special rules for parsing.

+7
source

You can set parentheses around uniq fonction:

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

output:

 $VAR1 = [ 2, 3, 4 ]; 
+3
source

Source: https://habr.com/ru/post/958914/


All Articles