如何在 Perl 中不使用 $b (比较)$a 的情况下对一个键升序排序,另一个键降序排序?
在 Perl 中,我可以这样做:
my @unit_indices = sort {
$units{$b}[0] <=> $units{$a}[0]
or
$a cmp $b
} keys %units;
按一个字段(数组元素)降序排序,另一个字段(哈希键)升序排序,但会导致 perlcritic
抱怨:
在 X 行、Y 列的排序块中禁止 $b 位于 $a 之前。请参阅 PBP 第 152 页。 (严重性:1)
Perl 最佳实践建议使用reverse
代替。
但是如果你这样写的话,操作会更容易理解:
@sorted_results = 反向排序@unsorted_results;
但是,我还没有找到一种方法来让子类别以相反的方向运行。
显然,我可以告诉 perlcritic
忽略这一点,但我想知道如何完成我需要的任务并让 perlcritic
满意。
In Perl, I can do:
my @unit_indices = sort {
$units{$b}[0] <=> $units{$a}[0]
or
$a cmp $b
} keys %units;
which sorts by one field (array element) descending and the other (hash key) ascending, but causes perlcritic
to complain:
Forbid $b before $a in sort blocks at line X, column Y. See page 152 of PBP. (Severity: 1)
Perl Best Practices recommends using reverse
instead.
But the operation would be much more comprehensible if you wrote:
@sorted_results = reverse sort @unsorted_results;
However, I haven't found a way to have subsorts that run in opposite directions.
Obviously, I can tell perlcritic
to ignore this, but I'd like to know how to accomplish what I need and make perlcritic
happy.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Perl::Critic 有时会更关心 PBP 的准确再现,而不是提出好的策略,而且一些 Perl 最佳实践 还没有很好地过时。例如,现在已经过时了 Miscellanea::RequireRcsKeywords< /a> 默认情况下仍处于打开状态。
Perl::Critic 的政策不应该被视为规范。他们缺乏进行主观分析的能力来确定“修复”是否实际上会增加复杂性,特别是当严重程度下降且收益越来越窄时。 BuiltinFunctions::ProhibitReverseSortBlock 是“装饰”级别政策,完全属于这一类。
虽然有人可能会跳过 $b cmp $a 并向后读取它,但一旦仔细查看,就不难理解,不值得之后反转整个数组的开销,并且当然不值得扭曲您的排序块以匹配策略分析的限制。他们决定不更改默认行为以将策略限制为简单排序块,在我看来是错误的。你的排序块显然超出了书面策略的范围,并且只是因为 Perl::Critic 的策略实现受到限制而被触发。
仅仅因为 Perl::Critic 有默认策略并不意味着它们代表了良好的实践,也不意味着它们应该被盲目遵循。您可以根据项目的喜好随意配置它,在最挑剔的级别运行 Perl::Critic 需要它。为了防止沉默 perlcritic 成为一种习惯,我建议在
.perlcritic
中选择项目范围的策略决策,而不是逐行单独关闭它们。请记住,重点不是要让批评者高兴,重点是编写更好的代码。
Perl::Critic at times will concern itself more with being an accurate reproduction of PBP than presenting good policy, and some of Perl Best Practices hasn't aged well. For example, the now woefully out of date Miscellanea::RequireRcsKeywords is still on by default.
Perl::Critic's policies shouldn't be treated as canon. They lack the ability to do subjective analysis to decide if the "fix" is actually going to increase complexity, particularly as the severity level drops and the benefits get narrower and narrower. BuiltinFunctions::ProhibitReverseSortBlock is a "cosmetic" level policy and falls squarely into this category.
While somebody might skip
$b cmp $a
and read it backwards, it is not difficult to comprehend once squarely looked at, is not worth the overhead of reversing the whole array afterward, and is certainly not worth contorting your sort block to match the limitations of the policy analysis. Their decision not to change the default behavior to limit the policy to simple sort blocks is IMO incorrect. Your sort block is obviously beyond the scope of the written policy and is only triggered because Perl::Critic's policy implementation is limited.Just because Perl::Critic has a policy on by default doesn't mean they represent good practice nor that they should be followed blindly. Feel free to configure it to your project's tastes, running Perl::Critic at its most picky levels requires it. In order to prevent silencing perlcritic from being a habitual thing, I would recommend preferring project-wide policy decisions in
.perlcritic
to individually turning them off line by line.Remember, the point is not to be perlcritic happy, the point is to write better code.
我同意 tchrist 的评论,但从表面上看你的问题:
1)使用
## no comment
2)使用
.perlcriticrc
文件3)改变比较的意义
I agree with tchrist's comment, but taking your question at face value:
1) use
## no critic
2) Use a
.perlcriticrc
file3) Change the sense of your comparison
随意使用 perlcritic,但不要成为它的奴隶。拥有
perlcritic
的全部意义在于能够发出很可能出错的警告。它肯定是在鼓励使用反向排序 { $a <=>; $b } 超过
sort { $b <=>; $a }
,但这不能在这里完成。不要为了消除虚假警告而使代码变得更糟。有时,警告是错误的,在这种情况下,您应该解决该警告。
Feel free to use perlcritic, but don't be a slave to it. The whole point of having
perlcritic
is to be have the ability to issue warnings that have a good chance of being wrong.It's surely trying to encourage the use of
reverse sort { $a <=> $b }
oversort { $b <=> $a }
, but that can't be done here.Don't make your code worse to silence a spurious warning. Sometimes, it's the warning that's wrong, in which case you should address the warning.