perlmodstyle
СОДЕРЖАНИЕ
- НАЗВАНИЕ
- ВВЕДЕНИЕ
- КРАТКИЙ СПИСОК ПРОВЕРКИ
- ПЕРЕД НАЧАЛОМ НАПИСАНИЯ МОДУЛЯ
- ПРОЕКТИРОВАНИЕ И НАПИСАНИЕ ВАШЕГО МОДУЛЯ
- ДОКУМЕНТИРОВАНИЕ ВАШЕГО МОДУЛЯ
- УЧЕТ ПРИ ВЫПУСКЕ
- ОБЩИЕ ОШИБКИ
- СМОТРИТЕ ТАКЖЕ
- АВТОР
НАЗВАНИЕ
perlmodstyle - Руководство по стилю Perl-модулей
ВВЕДЕНИЕ
В данном документе описаны «лучшие практики» Perl-сообщества для написания Perl-модулей. Он дополняет рекомендации, содержащиеся в perlstyle, которые следует считать обязательными к прочтению перед чтением данного документа.
Хотя данный документ предназначен для всех авторов модулей, он особенно адресован авторам, которые хотят опубликовать свои модули на CPAN.
В фокусе находятся те элементы стиля, которые видны пользователям модуля, а не те части, которые видят только разработчики модуля. Однако многие из приведенных в этом документе рекомендаций можно экстраполировать и успешно применить к внутренним частям модуля.
Данный документ отличается от perlnewmod тем, что это руководство по стилю, а не учебное пособие по созданию CPAN-модулей. Он предоставляет контрольный список для сравнения модулей, чтобы определить, соответствуют ли они лучшим практикам, не описывая подробно, как этого добиться.
Все рекомендации, содержащиеся в этом документе, были получены из обширных бесед с опытными авторами и пользователями CPAN. Каждый совет здесь — результат предыдущих ошибок. Эта информация поможет вам избежать тех же ошибок и дополнительных усилий, которые неизбежно потребуются для их исправления.
Первая часть этого документа предоставляет структурированный список проверок; последующие части предоставляют более подробное обсуждение пунктов списка. Заключительная часть, «Общие ошибки», описывает некоторые из самых распространенных ошибок, совершаемых авторами CPAN.
КРАТКИЙ СПИСОК ПРОВЕРКИ
Более подробную информацию по каждому пункту данного списка см. ниже.
Перед началом
-
Не переизобретайте колесо
-
При возможности исправьте, расширьте или создайте подкласс существующего модуля
-
Делайте одно дело и делайте его хорошо
-
Выберите подходящее имя
-
Получите отзывы перед публикацией
API
-
API должен быть понятен среднему программисту
-
Простые методы для простых задач
-
Разделение функциональности от вывода
-
Согласованное именование подпрограмм или методов
-
Используйте именованные параметры (хеш или хеш-ссылку), когда параметров более двух
Стабильность
-
Убедитесь, что ваш модуль работает под
use strictи-w -
Стабильные модули должны поддерживать обратную совместимость
Документация
-
Пишите документацию в формате POD
-
Документируйте цель, область применения и целевые приложения
-
Документируйте каждый публичный метод или подпрограмму, включая параметры и возвращаемые значения
-
Приводите примеры использования в документации
-
Предоставьте файл README, а также заметки о выпуске, журнал изменений и т.д.
-
Предоставьте ссылки на дополнительную информацию (URL, электронная почта)
Учет при выпуске
-
Укажите предварительные требования в файле Makefile.PL или Build.PL
-
Укажите требования к версии Perl с помощью
use -
Включите тесты в ваш модуль
-
Выберите разумную и последовательную схему нумерации версий (X.YY — распространенная схема нумерации Perl-модулей)
-
Увеличивайте номер версии при каждом изменении, независимо от его размера
-
Упакуйте модуль с помощью «make dist»
-
Выберите подходящую лицензию (GPL/Artistic — хорошее значение по умолчанию)
ПЕРЕД НАЧАЛОМ НАПИСАНИЯ МОДУЛЯ
Старайтесь не бросаться сразу в разработку модуля, не потратив некоторое время на предварительное обдумывание. Небольшое предварительное обдумывание может сэкономить вам массу усилий впоследствии.
Было ли это сделано раньше?
Возможно, вам даже не нужно писать модуль. Проверьте, не было ли этого сделано раньше в Perl, и избегайте переизобретения колеса, если у вас нет веской причины.
Хорошие места для поиска существующих модулей — MetaCPAN и PrePAN, а также обращение на module-authors@perl.org (https://lists.perl.org/list/module-authors.html).
Если существующий модуль почти выполняет то, что вам нужно, подумайте о написании исправления, написании подкласса или ином расширении существующего модуля, а не о его переписывании.
Делайте одно дело и делайте его хорошо
Рискуя сказать очевидное, модули предназначены для модульности. Разработчик Perl должен быть в состоянии использовать модули для построения строительных блоков своего приложения. Однако важно, чтобы блоки были правильной формы, и разработчик не должен использовать большой блок, когда ему нужен только небольшой.
Ваш модуль должен иметь четко определенную область применения, которая не превышает одного предложения. Можно ли разбить ваш модуль на семейство взаимосвязанных модулей?
Плохой пример:
"FooBar.pm предоставляет реализацию протокола FOO и связанного стандарта BAR."
Хороший пример:
"Foo.pm предоставляет реализацию протокола FOO. Bar.pm реализует связанный протокол BAR."
Это означает, что если разработчику нужен только модуль для стандарта BAR, он не должен быть вынужден устанавливать библиотеки для FOO тоже.
Что в имени?
Убедитесь, что вы выбрали подходящее имя для своего модуля на ранней стадии. Это поможет людям находить и запоминать ваш модуль, а также сделает программирование с вашим модулем более интуитивно понятным.
При выборе имени модуля учитывайте следующее:
-
Будьте описательными (т.е. точным описанием назначения модуля).
-
Согласовывайтесь с существующими модулями.
-
Отражайте функциональность модуля, а не реализацию.
-
Избегайте создания новой иерархии верхнего уровня, особенно если уже существует подходящая иерархия, в которой можно разместить ваш модуль.
Получите отзывы перед публикацией
Если вы никогда не загружали модуль на CPAN раньше (и даже если вы это делали), настоятельно рекомендуется получить отзывы на PrePAN. PrePAN — это сайт, посвященный обсуждению идей для CPAN-модулей с другими разработчиками Perl, и это отличный ресурс для начинающих (и опытных) разработчиков Perl.
Вы также должны попытаться получить отзывы от людей, которые уже знакомы с областью применения модуля и системой именования CPAN. Авторы похожих модулей или модулей с похожими именами могут быть хорошим началом, как и сообщества, такие как Perl Monks.
ПРОЕКТИРОВАНИЕ И НАПИСАНИЕ ВАШЕГО МОДУЛЯ
Учет при проектировании и кодировании модуля:
Объектно-ориентированное программирование (ООП) или нет?
Ваш модуль может быть объектно-ориентированным (ООП) или нет, или он может иметь оба вида интерфейсов, доступных для использования. Существуют преимущества и недостатки каждого метода, которые следует учитывать при проектировании вашего API.
В «Perl Best Practices» (авторство 2004 г., издательство O'Reilly Media, Inc.) Damian Conway предоставляет список критериев, которые следует использовать при решении вопроса о том, подходит ли ООП для вашей проблемы:
-
Разрабатываемая система большая или, вероятно, станет большой.
-
Данные могут быть агрегированы в очевидные структуры, особенно если в каждом агрегате много данных.
-
Различные типы агрегатов данных образуют естественную иерархию, которая способствует использованию наследования и полиморфизма.
-
У вас есть фрагмент данных, к которому применяется множество различных операций.
-
Вам необходимо выполнять одни и те же общие операции над связанными типами данных, но с небольшими вариациями в зависимости от конкретного типа данных, к которому применяются операции.
-
Вероятно, вам придется добавлять новые типы данных позже.
-
Типичные взаимодействия между фрагментами данных лучше всего представлены операторами.
-
Реализация отдельных компонентов системы, вероятно, будет меняться со временем.
-
Дизайн системы уже ориентирован на объекты.
-
Ваши модули кода будут использоваться большим количеством других программистов.
Внимательно подумайте, подходит ли ОО для вашего модуля. Напрасное использование объектно-ориентированного подхода приводит к сложным API, которые сложно понять или использовать среднему пользователю модуля.
Проектирование вашего API
Ваши интерфейсы должны быть понятны среднему программисту Perl. Следующие рекомендации могут помочь вам оценить, достаточно ли простым является ваш API:
- Описывайте простые процедуры для выполнения простых задач.
-
Лучше иметь множество простых процедур, чем несколько монолитных. Если поведение вашей процедуры существенно меняется в зависимости от ее аргументов, это признак того, что вам следует иметь две (или более) отдельные процедуры.
- Разделяйте функциональность и вывод.
-
Возвращайте результаты в максимально обобщенной форме и позволяйте пользователю выбирать, как их использовать. Наиболее обобщенная форма — обычно структура данных Perl, которая затем может быть использована для генерации текстового отчета, HTML, XML, запроса к базе данных или чего-либо еще, что требуют ваши пользователи.
Если ваша процедура итерируется по некоторому списку (например, списку файлов или записей в базе данных), вы можете рассмотреть возможность предоставления обратного вызова, чтобы пользователи могли манипулировать каждым элементом списка по очереди. File::Find предоставляет пример этого со своим синтаксисом
find(\&wanted, $dir). - Предоставляйте разумные сокращения и значения по умолчанию.
-
Не заставляйте каждого пользователя модуля проходить одни и те же сложности для достижения простого результата. Вы всегда можете включить необязательные параметры или процедуры для более сложного или нестандартного поведения. Если большинство ваших пользователей вынуждены писать несколько почти одинаковых строк кода при первом использовании вашего модуля, это признак того, что вам следует сделать это поведение значением по умолчанию. Другим хорошим показателем, что вам следует использовать значения по умолчанию, является то, если большинство ваших пользователей вызывают ваши процедуры с одинаковыми аргументами.
- Конвенции именования
-
Ваше именование должно быть последовательным. Например, лучше иметь:
display_day(); display_week(); display_year();чем
display_day(); week_display(); show_year();Это относится и к именам методов, именам параметров, и ко всему остальному, что видно пользователю (и большинству того, что не видно!)
- Передача параметров
-
Используйте именованные параметры. Проще использовать хеш, как в этом примере:
$obj->do_something( name => "wibble", type => "text", size => 1024, );... чем иметь длинный список безымянных параметров, как в этом примере:
$obj->do_something("wibble", "text", 1024);Хотя список аргументов может хорошо работать для одного, двух или даже трех аргументов, большее количество аргументов становится трудно запомнить пользователю модуля и трудно управлять автору модуля. Если вы хотите добавить новый параметр, вам придется добавить его в конец списка для обратной совместимости, и это, вероятно, сделает порядок вашего списка неинтуитивным. Кроме того, если многие элементы могут быть неопределенными, вы можете увидеть следующие непривлекательные вызовы методов:
$obj->do_something(undef, undef, undef, undef, undef, 1024);Устанавливайте разумные значения по умолчанию для параметров, которые их имеют. Не заставляйте пользователей указывать параметры, которые почти всегда будут одинаковыми.
Вопрос о том, передавать ли аргументы в хеше или в hashref, в основном зависит от личного стиля.
Использование ключей хеша, начинающихся с тире (
-name) или полностью заглавных (NAME) — это пережиток старых версий Perl, в которых обычные строчные символы не обрабатывались корректно оператором=>. Хотя некоторые модули сохраняют заглавные или с тире имена аргументов по историческим причинам или по личным предпочтениям, большинство новых модулей должны использовать простые строчные ключи. Какой бы вариант вы ни выбрали, будьте последовательны!
Строгость и предупреждения
Ваш модуль должен успешно работать с директивой strict и без генерации предупреждений. Ваш модуль также должен обрабатывать проверку на заражение (taint-checking), где это уместно, хотя это может вызвать трудности во многих случаях.
Обратная совместимость
Модули, которые являются «стабильными», не должны нарушать обратную совместимость без, по крайней мере, длительного переходного периода и существенного изменения номера версии.
Обработка ошибок и сообщения
Когда ваш модуль обнаруживает ошибку, он должен сделать одно или несколько из следующих:
-
Возвратить неопределенное значение.
-
установить
$Module::errstrили аналогичное (errstr— общее имя, используемое модулями DBI и другими популярными модулями; если вы выберете что-то другое, убедитесь, что это четко задокументировано). -
warn()илиcarp()сообщение в STDERR. -
croak()только когда ваш модуль абсолютно не может понять, что делать. (croak()— лучшая версияdie()для использования внутри модулей, которая сообщает об ошибках с точки зрения вызывающей стороны. См. Carp для получения подробностей оcroak(),carp()и других полезных процедурах.) -
В качестве альтернативы вышеперечисленному, вы можете предпочесть использовать исключения с использованием модуля Error.
Настраиваемая обработка ошибок может быть очень полезна для ваших пользователей. Подумайте о предоставлении выбора уровней предупреждений и отладочных сообщений, возможности отправки сообщений в отдельный файл, способа указания процедуры обработки ошибок или других подобных функций. Убедитесь, что по умолчанию все эти опции настроены на наиболее часто используемые варианты.
ДОКУМЕНТИРОВАНИЕ ВАШЕГО МОДУЛЯ
POD
Ваш модуль должен содержать документацию, ориентированную на разработчиков Perl. Вы должны использовать "простую документацию" (POD) Perl для общей технической документации, хотя вы можете захотеть написать дополнительную документацию (белые книги, учебники и т. д.) в другом формате. Вам нужно охватить следующие темы:
-
Обзор распространенных способов использования модуля
-
Цель, область применения и целевые приложения вашего модуля
-
Использование каждого публично доступного метода или подпрограммы, включая параметры и возвращаемые значения
-
Примеры использования
-
Источники дополнительной информации
-
Адрес электронной почты для автора/администратора
Уровень детализации в документации модуля Perl обычно варьируется от менее подробного до более подробного. Раздел SYNOPSIS должен содержать минимальный пример использования (возможно, всего одну строку кода; пропустите необычные случаи использования или что-либо, что не нужно большинству пользователей); описание должно описывать ваш модуль в общих чертах, обычно в нескольких абзацах; более подробная информация о процедурах или методах модуля, подробные примеры кода или другая углубленная информация должны быть даны в последующих разделах.
В идеале, тот, кто немного знаком с вашим модулем, должен иметь возможность освежить свои знания, не нажимая «вниз по странице». По мере того, как читатель продолжает просматривать документ, он должен получать всё больше и больше знаний.
Рекомендуемый порядок разделов в документации модуля Perl:
-
ИМЯ
-
СИНТЕЗ
-
ОПИСАНИЕ
-
Один или несколько разделов или подразделов, предоставляющих более подробную информацию о доступных методах и процедурах и любой другой соответствующей информации.
-
ОШИБКИ/ОСОБЕННОСТИ/и т. д.
-
АВТОР
-
СМОТРИТЕ ТАКЖЕ
-
АВТОРСКИЕ ПРАВА и ЛИЦЕНЗИЯ
Держите документацию рядом с кодом, к которому она относится ("встраиваемая" документация). Включите POD для данного метода прямо над подпрограммой этого метода. Это облегчает обновление документации и позволяет избежать необходимости документировать каждый фрагмент кода дважды (раз в POD и раз в комментариях).
README, INSTALL, заметки о релизе, журналы изменений
Ваш модуль также должен включать файл README, описывающий модуль и дающий указания на дополнительную информацию (веб-сайт, электронный адрес автора).
В файл INSTALL следует включить простые инструкции по установке. При использовании ExtUtils::MakeMaker это обычно будет:
- perl Makefile.PL
- make
- make test
- make install
При использовании Module::Build это обычно будет:
- perl Build.PL
- perl Build
- perl Build test
- perl Build install
Заметки о релизе или журналы изменений должны создаваться для каждой версии вашего программного обеспечения, описывая изменения в вашем модуле, видимые пользователю.
Если у вас нет веских причин использовать какой-либо другой формат (например, формат, используемый в вашей компании), конвенцией является именование файла журнала изменений Changes, и следование простому формату, описанному в CPAN::Changes::Spec.
СООБРАЖЕНИЯ ОТНОСИТЕЛЬНО ВЫПУСКА
Нумерация версий
Номера версий должны указывать, по крайней мере, основные и второстепенные релизы, и, возможно, подвторостепенные релизы. Основной релиз — это тот, в котором изменена большая часть функциональности или добавлены основные новые функции. Второстепенный релиз — это тот, в котором добавлена или изменена небольшая часть функциональности. Подвторостепенные номера версий обычно используются для изменений, которые не влияют на функциональность, таких как исправления документации.
Самая распространенная схема нумерации версий CPAN выглядит так:
1.00, 1.10, 1.11, 1.20, 1.30, 1.31, 1.32 Правильный номер версии CPAN — это число с плавающей запятой, содержащее не менее 2 цифр после десятичной точки. Вы можете проверить, соответствует ли он CPAN, используя
perl -MExtUtils::MakeMaker -le 'print MM->parse_version(shift)' \
'Foo.pm' Если вы хотите выпустить «бета» или «альфа» версию модуля, но не хотите, чтобы CPAN.pm отображал её как самую последнюю, добавьте «_» после обычного номера версии, за которым следуют не менее 2 цифр, например 1.20_01. Если вы это сделаете, рекомендуется следующий код:
our $VERSION = "1.12_01"; # so CPAN distribution will have
# right filename
our $XS_VERSION = $VERSION; # only needed if you have XS code
$VERSION = eval $VERSION; # so "use Module 0.002" won't warn on
# underscore С помощью этого трюка MakeMaker будет читать только первую строку, и, таким образом, читать символ подчёркивания, в то время как интерпретатор Perl будет оценивать $VERSION и преобразовывать строку в число. Более поздние операции, которые обрабатывают $VERSION как число, смогут сделать это без предупреждения о том, что $VERSION не является числом.
Никогда не выпускайте ничего (даже исправление документации в одно слово) без увеличения номера. Даже исправление документации в одно слово должно привести к изменению версии на подвторостепенном уровне.
После выбора важно придерживаться вашей схемы версий, не уменьшая количество цифр. Это связано с тем, что «нижестоящие» сборщики пакетов, такие как система портов FreeBSD, интерпретируют номера версий различными способами. Если вы измените количество цифр в вашей схеме версий, вы можете сбить с толку эти системы, так что они получат версии вашего модуля в неправильном порядке, что, очевидно, плохо.
Предварительные требования
Авторы модулей должны тщательно взвесить, стоит ли полагаться на другие модули и на какие именно модули полагаться.
Самое главное — выбирайте модули, которые максимально стабильны. В порядке предпочтения:
-
Основные модули Perl
-
Стабильные модули CPAN
-
Нестабильные модули CPAN
-
Модули, недоступные из CPAN
Укажите требования к версиям других модулей Perl в предварительных требованиях в вашем файле Makefile.PL или Build.PL.
Обязательно укажите требования к версиям Perl как в Makefile.PL или Build.PL, так и с помощью require 5.6.1 или аналогичного. См. раздел use VERSION в "require" в perlfunc для получения подробностей.
Тестирование
Все модули должны быть протестированы перед распространением (используя «make disttest»), а тесты также должны быть доступны пользователям, устанавливающим модули (используя «make test»). Для Module::Build вы бы использовали эквивалент make test perl Build test.
Важность этих тестов пропорциональна предполагаемой стабильности модуля. Модуль, который претендует на стабильность или надеется на широкое использование, должен придерживаться максимально строгих тестов.
Полезные модули для написания тестов (с минимальным влиянием на процесс разработки и время) включают Test::Simple, Carp::Assert и Test::Inline. Для более сложных наборов тестов существуют Test::More и Test::MockObject.
Упаковки
Модули должны быть упакованы с использованием одного из стандартных инструментов для упаковки. В настоящее время у вас есть выбор между ExtUtils::MakeMaker и более независимым от платформы Module::Build, позволяющим устанавливать модули последовательным образом. При использовании ExtUtils::MakeMaker вы можете использовать «make dist» для создания вашего пакета. Существуют инструменты, которые помогут вам собрать ваш модуль в стиле MakeMaker. К ним относятся ExtUtils::ModuleMaker и h2xs. См. также perlnewmod.
Лицензирование
Убедитесь, что у вашего модуля есть лицензия, и что полный текст лицензии включен в дистрибутив (если это не распространенная лицензия и условия лицензии не требуют ее включения).
Если вы не знаете, какую лицензию использовать, двойная лицензия по GPL и Artistic (такая же, как у Perl) — хорошая идея. См. perlgpl и perlartistic.
Общие ошибки
Переизобретение колеса
Существуют определенные области применения, которые уже очень хорошо обслуживаются CPAN. Один пример — системы шаблонов, другой — модули даты и времени, и их гораздо больше. Хотя это традиционный опыт написать свою собственную версию этих вещей, пожалуйста, тщательно взвесьте, действительно ли Perl-мир нуждается в вашей публикации.
Попытка сделать слишком много
Ваш модуль будет частью инструментария разработчика. Он не будет сам по себе образовывать весь инструментарий. Искушение добавить дополнительные функции до тех пор, пока ваш код не станет монолитной системой, а не набором модульных строительных блоков.
Неподходящая документация
Не попадите в ловушку написания документации для неправильной аудитории. Вашей основной аудиторией является достаточно опытный разработчик с, по крайней мере, умеренным пониманием области применения вашего модуля, который только что скачал ваш модуль и хочет как можно быстрее начать его использовать.
Учебники, документация для конечных пользователей, исследовательские статьи, часто задаваемые вопросы и т. д. не подходят для основной документации модуля. Если вы действительно хотите написать их, включите их как поддокументы, такие как My::Module::Tutorial или My::Module::FAQ, и предоставьте ссылку в разделе «См. также» основной документации.
См. также
- perlstyle
-
Общие рекомендации по стилю Perl
- perlnewmod
-
Как создать новый модуль
- perlpod
-
Документация POD
- podchecker
-
Проверяет правильность вашего POD
- Инструменты упаковки
- Инструменты тестирования
-
Test::Simple, Test::Inline, Carp::Assert, Test::More, Test::MockObject
- https://pause.perl.org/
-
Сервер загрузки авторов Perl. Содержит ссылки на информацию для авторов модулей.
- Любая хорошая книга по программной инженерии
АВТОР
Kirrily «Skud» Robert <skud@cpan.org>
© 1993–2020 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.32.0/perlmodstyle