That code falls under the sort invocation of
sort SUBNAME LIST
...
If SUBNAME is specified, it gives the name of a subroutine that returns an integer less than, equal to, or greater than 0 , depending on how the elements of the list are to be ordered.
The uniq
in the first example is taken as a bareword that specifies the name of the sub to use for sorting and qw(b a a)
is the list to sort -- you aren't uniq
-ing the list (so to speak) but are using uniq
as a sorting function for that list.
The error message comes as a sorting function needs to return a number and uniq
returns strings.
You've discovered one way to make it work, and can also use the unary +
say for sort +uniq(@ary); # or: say for sort + uniq @ary;
since what follows +
is treated as an expression, so sort
gets the evaluated list. See this post and this post for discussion of such uses of the unary +
.
Or use parens through and through
say for sort (uniq(@ary));
Here the inner pair is also necessary since with sort (uniq @ary)
the uniq
is interpreted as a bareword in that list, thus out of place. Note that sort (uniq (@ary))
won't work since extra parens don't matter and we again have a bareword; so that space matters here!
This trickiness is due to sort
's flexible (ambiguous) interface, taking a LIST
optionally preceded by a bareword, which need be a sub name. It ends up relying on the interpreter to sort out some of that and then we have to be precise.
sort uniq ...
is interpreted as thesort SUBNAME LIST
syntax whereSUBNAME
isuniq
instead of the intendedsort LIST
syntax. You can achieve the latter usingsort @{[uniq ("b", "a", "a")]}
– Incestuoussort (uniq @list)
parsed assort LIST
syntax whensort ("a","b","c")
is? Is this just a strange quirk of the Perl parser? – Citrangesort (uniq @ary)
there is no reason for the interpreter to see thatuniq
is anything other than a bareword in that list (and is thus out of place). Thussort (uniq(@ary));
works – Bixlersort
's syntax is what's quirky. Specifically, it's very ambigous, so Perl needs to perform all kinds of guesses. – Fasciclesort(uniq(@ary))
works,sort(uniq (@ary))
does not. The only difference is the space I added betweenuniq
and(@ary)
. I always thought whitespace was not semantically significant! – Ingeminate(word (@ary))
is no different from(word @ary)
. It's a good point though, that li'l space does count here (undersort
) – Bixler