问题
use List::MoreUtils 'uniq';
print join ", ", sort uniq ("b", "a", "a");
results in Argument "a" isn't numeric in sort at ...
print join ", ", uniq sort ("b", "a", "a");
works as expected.
print join ", ", sort {$a cmp $b} uniq ("b", "a", "a");
works too - but what is the problem with the first example?
回答1:
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.
来源:https://stackoverflow.com/questions/57444597/isnt-numeric-error-in-sort-after-uniq