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, и избегайте переизобретения колеса, если у вас нет веской причины.
Хорошие места для поиска существующих модулей включают http://search.cpan.org/ и https://metacpan.org, а также запросы на module-authors@perl.org (http://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.) Дэймиан Конвей приводит список критериев, которые следует использовать при решении вопроса, подходит ли ООП для вашей задачи:
-
Разрабатываемая система большая или, вероятно, станет большой.
-
Данные могут быть агрегированы в очевидные структуры, особенно если в каждом агрегате много данных.
-
Различные типы агрегатов данных образуют естественную иерархию, которая способствует использованию наследования и полиморфизма.
-
У вас есть фрагмент данных, к которому применяется множество различных операций.
-
Вам необходимо выполнять одни и те же общие операции над связанными типами данных, но с небольшими вариациями в зависимости от конкретного типа данных, к которому применяются операции.
-
Вероятно, вам придется добавлять новые типы данных позже.
-
Типичные взаимодействия между фрагментами данных лучше всего представлены операторами.
-
Реализация отдельных компонентов системы, вероятно, будет меняться со временем.
-
Дизайн системы уже ориентирован на объекты.
-
Ваши модули кода будут использоваться большим количеством других программистов.
Внимательно подумайте, подходит ли ОО для вашего модуля. Напрасное использование объектно-ориентированного подхода приводит к сложным 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
- http://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.30.3/perlmodstyle