Perlcritic - прототипы подпрограмм - PullRequest
0 голосов
/ 20 декабря 2011

Я получаю эту ошибку при запуске Perlcritic:

Прототипы подпрограмм, используемые в строке xx, столбце x.См. Страницу 194 PBP.(Уровень серьезности: 5)

Подпрограмма:

sub zFormatDate() {
  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = shift;
  return sprintf("%04d%02d%02d%02d%02d%02d",
    $year + 1900, $mon+1, $mday, $hour, $min, $sec);
}

Если я удалю ключевое слово 'sub' из своей функции, оно исчезнет.

Это нормально?, или я должен искать другое решение?

Ответы [ 4 ]

19 голосов
/ 20 декабря 2011

Нет, удаление ключевого слова sub определенно не решение. Если вы измените это:

sub func($@) {
    # ...
}

к этому:

func($@) {
    # ...
}

perlcritic перестает жаловаться на прототип - но я думаю, что это просто сбой в perlcritic. Без ключевого слова sub это больше не определение подпрограммы; это синтаксическая ошибка, как вы увидите, попытаетесь ли вы ее запустить или отметите perl -cw. Задача Perlcritic не в том, чтобы проверить, является ли ваш код допустимым Perl; он, очевидно, предполагает, что это так, а затем предупреждает вас о проблемах стиля. Если вы введете недопустимый Perl, все ставки отключены.

В наши дни принято считать, что использование прототипов Perl обычно не очень хорошая идея.

Perlcritic основан на книге "Лучшие практики Perl" Дамиана Конвея. Раздел, начиная со страницы 194, называется «Не используйте прототипы подпрограмм».

Книга не является общедоступной, поэтому я не могу цитировать или ссылаться на раздел здесь, но у chromatic есть запись в блоге "Проблема с прототипами", в которой, среди прочего, говорится:

Основная проблема с прототипами заключается в том, что они ведут себя иначе, чем большинство людей ожидают, когда впервые сталкиваются с ними. Прототипы могут меняться парсинг последующего кода, и они могут привести типы аргументы. Они не служат документацией для количества или типов подпрограммы аргументов ожидают и не отображают аргументы в именованные параметры.

Легко предположить, что прототипы Perl похожи на прототипы C, которые объявляют число и тип (ы) (и, возможно, имена) аргументов, которые ожидает функция. На самом деле они совсем другие. Их основная цель заключается в написании подпрограмм Perl, которые имитируют поведение встроенных функций, например, не сплющивая массивы в списки.

См. Также perldoc perlsub:

Это все очень мощно, конечно, и должно использоваться только в умеренность, чтобы сделать мир лучше.

17 голосов
/ 20 декабря 2011

Как видно из сообщения, вы использовали прототипы подпрограмм .Скорее всего, они вам не нужны.

В настоящее время определение вашей подпрограммы может быть похоже на:

sub foo()

Измените его на:

sub foo

Обратите внимание на удаление ( и ) и все что между ними.

9 голосов
/ 20 декабря 2011

Perl :: Critic считает прототипы подпрограмм плохими.Дело не в ключевом слове sub, а в определении аргументов функции.Удаление «sub» заставит Perl :: Critic не сообщать об ошибке, но ваш код все равно не запустится

Возможно, вы захотите использовать прототипы подпрограмм в одном из следующих двух сценариев:

  1. вы хотите выполнить "магию" с параметрами вашей функции, например:

    sub fun1 (\ @) {my ($ ar_ref) = @_}

поэтому вызов, подобный

fun1(@args)  

, не перетянет @args в @_, но передаст @args в качестве ссылки на массив в @_ [0]

  1. Вы хотите четко указать сигнатуру функции

    sub fun2 ($$ \%) {}

Аргументы fun2 - скаляр, другой скаляри ссылка на хэш

Книга Perl Best Practice дает сценарии использования для обоих случаев, в которых вы довольно легко запутаетесь в своем собственном коде.PBP предлагает следующее исправление: не используйте прототипы.

Если вы все еще хотите их использовать, вы можете указать Perl :: Critic не сообщать об использовании прототипов:

## no critic
# Perl::Critic will ignore any problems it sees with your code
sub func_With_prototypes ($$$)
{
return undef
}
## use critic
# Perl::Critic will report any problems it sees within your code
2 голосов
/ 27 июня 2019

Более новые Perls имеют функцию подписи, которая все еще помечена как экспериментальная, но довольно популярна, что помечено этим правилом.Подписи были введены после этого оригинального сообщения и, возможно, были тем, чего хотел En-Motion.

Поскольку в Catalyst широко используются прототипы, их нельзя использовать.Catalyst взламывает прототипы, чтобы обеспечить динамическую систему маршрутизации.

Если вы используете функцию подписи (или Catalyst), лучшим решением будет отключить правило через ~ / .perlcriticrc.

Добавьте следующее в ~ / .perlcriticrc

[- Подпрограммы :: ProhibitSubroutinePrototypes]

Хотя подписи выглядят как прототипы для PerlCritic, они являются существеннымиэлемент современного Perl-программирования.

рассмотрим:

sub add2nums {my $ num1 = shift;мой $ num2 = смещение;вернуть $ num1 + $ num2;}

с подписью:

использовать функцию 'подписи';

sub add2nums ($ num1, $ num2) {return $ num1 + $ num2;}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...