2

在 Perl 中,我可以这样做:

my @unit_indices = sort { 
    $units{$b}[0] <=> $units{$a}[0] 
        or
    $a cmp $b
} keys %units;

它按一个字段(数组元素)降序和另一个(哈希键)升序排序,但会导致perlcritic抱怨:

在 X 行 Y 列的排序块中禁止在 $a 之前使用 $b。参见 PBP 第 152 页。(严重性:1)

Perl Best Practices建议使用reverse

但是如果你写下这个操作会更容易理解:
@sorted_results = reverse sort @unsorted_results;

但是,我还没有找到一种方法让子排序以相反的方向运行。

显然,我可以告诉perlcritic忽略这一点,但我想知道如何完成我需要的事情并让自己perlcritic开心。

4

3 回答 3

9

Perl::Critic 有时会更多地关注 PBP 的准确再现,而不是提出好的政策,而且一些Perl 最佳实践还没有很好地老化。例如,现在严重过时的Miscellanea::RequireRcsKeywords默认仍处于启用状态。

Perl::Critic 的政策不应被视为经典。他们缺乏进行主观分析来确定“修复”是否真的会增加复杂性的能力,尤其是在严重程度下降并且收益越来越窄的情况下。 BuiltinFunctions::ProhibitReverseSortBlock是一个“化妆品”级别的策略,完全属于这一类。

虽然有人可能会跳过$b cmp $a并向后阅读它,但一旦正视它并不难理解,不值得在之后反转整个数组的开销,当然也不值得扭曲你的排序块以匹配策略分析的限制。他们决定不更改默认行为以将策略限制为简单的排序块是 IMO 不正确的。您的排序块显然超出了书面策略的范围,并且仅因为 Perl::Critic 的策略实施受到限制而被触发。

仅仅因为 Perl::Critic 有一个默认的策略并不意味着它们代表了良好的实践,也不意味着它们应该被盲目地遵循。随意根据您的项目的喜好对其进行配置,在最挑剔的级别上运行 Perl::Critic 需要它。为了防止沉默 perlcritic 成为一种习惯性的事情,我建议更喜欢项目范围的政策决策,.perlcritic而不是逐行单独关闭它们。

记住,关键不是要过分高兴,关键是要写出更好的代码。

于 2012-02-22T20:41:28.000 回答
4

我同意 tchrist 的评论,但从表面上看你的问题:

1) 使用## no critic

my @unit_indices = sort {   ## no critic (ReverseSortBlock)
    $units{$b}[0] <=> $units{$a}[0] 
        or
    $a cmp $b
} keys %units;

2)使用.perlcriticrc文件

[-BuiltinFunctions::ProhibitReverseSortBlock]

3)改变你的比较感

my @unit_indices = sort { 
    -($units{$a}[0] <=> $units{$b}[0])
        or
    $a cmp $b
} keys %units;

my @unit_indices = sort { 
    -$units{$a}[0] <=> -$units{$b}[0])
        or
    $a cmp $b
} keys %units;
于 2012-02-22T16:47:27.040 回答
2

随意使用 perlcritic,但不要成为它的奴隶。拥有的全部意义在于perlcritic能够发出很可能出错的警告。

它肯定是在鼓励使用reverse sort { $a <=> $b }over sort { $b <=> $a },但这不能在这里完成。

不要让您的代码变得更糟以消除虚假警告。有时,这是错误的警告,在这种情况下,您应该解决警告。

于 2012-02-22T22:34:41.410 回答