“isn't numeric” error in “sort” after “uniq”

孤人 提交于 2020-05-14 17:21:55

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!