2012-02-22 3 views
2

В Perl, я могу сделать:

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

, который сортирует по одному полю (массив элементов), сходящего и другой (хэш-ключ) восходящей, но вызывает perlcritic жаловаться:

упаси $ B перед $ a в блоках сортировки по строке X, столбец Y. См. стр. 152 PBP. (Серьезность: 1)

Perl Best Practices рекомендует использовать вместо reverse.

Но операция была бы гораздо более понятной, если Вы писали:
@sorted_results = обратный порядок сортировки @unsorted_results;

Однако я не нашел способ иметь подсерии, которые работают в противоположных направлениях.

Очевидно, я могу сказать perlcritic, чтобы проигнорировать это, но я хотел бы знать, как выполнить то, что мне нужно, и сделать perlcritic счастливым.

+1

Почему в мире вы бы использовали непобедимый 'perlcritic' ??? Это невероятно ошеломительно. Это твоя первая ошибка. Во-вторых, вы путаете советы PBP. Ваша начальная функция сортировки прекрасна, за исключением того, что я, конечно, избегаю 'или' вместо' || 'для улучшения удобочитаемости. Ваш вопрос озадачен, потому что вы четко знаете правильный способ сделать это уже. – tchrist

+0

Ваш код выглядит хорошо. Звучит как ошибка в perlcritic - $ a и $ b являются действительными perl-переменными для сортировки. Он должен только предупреждать, что $ a и $ b существуют вне блока сортировки для этой области действия и любых блоков внутри цикла. Похоже, он не обнаруживает множественные ключи. – Rich

+1

Аналогичная проблема была сообщена https://rt.cpan.org/Public/Bug/Display.html?id=36129 – toolic

ответ

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; 
+5

Ick. Не делайте 3, это просто делает ваш код сложнее понять для реальных людей, которые не являются роботами. – cjm

+0

@cjm - означает ли это, что я робот? :) – DVK

+1

Нам нужен оператор '> = <' в Perl 5.16! – mob

9

Perl :: Критик порой больше будет относиться к тому, чтобы быть точным воспроизведением PBP, чем представлять хорошую политику, а некоторые из Perl Best Practices не выдерживали хорошо. Например, по-прежнему устарело Miscellanea::RequireRcsKeywords.

Perl :: Политика критика не должна рассматриваться как канон. У них нет способности делать субъективный анализ, чтобы решить, действительно ли «исправление» будет увеличивать сложность, особенно когда уровень серьезности падает, а преимущества становятся все более узкими и уже. BuiltinFunctions::ProhibitReverseSortBlock - это «косметическая» политика уровня и попадает прямо в эту категорию.

В то время как кто-то может пропустить $b cmp $a и прочитать его в обратном направлении, это не сложно понять, если посмотреть на него прямо, не стоит накладных расходов на вспять весь массив после этого и, безусловно, не стоит искажать ваш блок сортировки, чтобы соответствовать ограничениям анализа политики. Их решение не изменять поведение по умолчанию, чтобы ограничить политику простыми блоками сортировки, неверно. Ваш блок сортировки явно выходит за рамки письменной политики и запускается только потому, что реализация политики Perl :: Critic ограничена.

Просто потому, что Perl :: Critic имеет политику по умолчанию, не означает, что они представляют собой хорошую практику или что они должны слепо следовать. Не стесняйтесь настраивать его на вкус вашего проекта, для этого нужен Perl :: Critic на самых придирчивых уровнях.Для того, чтобы не допустить, чтобы perlcritic от глупости стал привычным, я бы рекомендовал предпочесть решения политики в масштабе всего проекта в .perlcritic, чтобы индивидуально их отстроить.

Помните, что дело не в том, чтобы быть довольным счастливым, дело в том, чтобы написать лучший код.

+1

+1. Согласен. Вопрос моего вопроса, который я должен был четко сформулировать, состоял в том, что я хотел знать, что такое альтернатива, чтобы я мог принять взвешенное решение относительно выборочного игнорирования предупреждения. –

+1

Well⁠⁠ said.⁠⁠⁠⁠⁠⁠⁠⁠⁠⁠ – tchrist

2

Не стесняйтесь использовать perlcritic, но не являйтесь его подчиненным. Весь смысл иметь perlcritic должен иметь возможность выдавать предупреждения, которые имеют хорошие шансы быть неправильными.

Обязательно используйте reverse sort { $a <=> $b } более sort { $b <=> $a }, но это невозможно сделать здесь.

Не делайте код хуже, чтобы отключить ложное предупреждение. Иногда это предупреждение является неправильным, и в этом случае вам следует обратиться к предупреждению.

+0

Do * you * use 'perlcritic'? Я был бы удивлен, узнав об этом. – tchrist

+0

@tchrist, я полагаю, я имел в виду «Не стесняйтесь использовать perlcritic» вместо «Использовать perlcritic». (Исправлено) Я попытался создать профиль на работе (в основном для моих коллег), но стало похоже, что это пустая трата времени. Слишком много плохих звонков. Я не могу представить, чтобы кто-то пытался испортить их код, чтобы заставить их замолчать. – ikegami

+3

Я нахожу идею perlcritic worthwhile. Он просматривает мое плечо и держит меня честным. За эти годы я сформулировал это по своей воле и прокомментировал мои соображения. Возможно, лучше начать. https: // GitHub.com/schwern/test-more/blob/Test-Builder1.5/.perlcriticrc – Schwern

 Смежные вопросы

  • Нет связанных вопросов^_^