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)]);
The output is
unique results
$VAR1 = [
3,
2,
4
];
sorted unique results
$VAR1 = [
2,
3,
3,
4
];
So it looks that sort does not work with uniq. I did not understand why.
I ran the 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 using uniq as a function of sort.
Why did perl decide to do it?
How can i avoid these and similar pitfalls?
Thanks, David
The sort
builtin accepts a subroutine name or block as first argument which is passed two items. It then must return a number which determines the order between the items. These snippets all do the same:
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;
Notice that there isn't any comma between the function name and the list, and note that the parens in Perl are primarly used to determine precedence – sort func1 @letters
and sort func1 (@letters)
are the same, and neither executes func1(@letters)
.
To disambiguate, place a +
before the function name:
sort +uniq @letters;
To avoid such unexpected behaviour, the best solution is to read the docs when you aren't sure how a certain builtin behaves – unfortunately, many have some special parsing rules.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With