perlmodstyle
СОДЕРЖАНИЕ
- НАЗВАНИЕ
- ВВЕДЕНИЕ
- БЫСТРЫЙ СПИСОК ПРОВЕРКИ
- ПЕРЕД НАЧАЛОМ НАПИСАНИЯ МОДУЛЯ
- ПРОЕКТИРОВАНИЕ И НАПИСАНИЕ ВАШЕГО МОДУЛЯ
- ДОКУМЕНТИРОВАНИЕ ВАШЕГО МОДУЛЯ
- СООБРАЖЕНИЯ ПО ВЫПУСКУ
- ОБЩИЕ ОШИБКИ
- СМОТРИТЕ ТАКЖЕ
- АВТОР
НАЗВАНИЕ
perlmodstyle - Руководство по стилю модулей Perl
ВВЕДЕНИЕ
В данном документе представлен подход сообщества Perl к "лучшей практике" написания модулей Perl. Он расширяет рекомендации, представленные в perlstyle, которые следует прочитать перед чтением этого документа.
Хотя этот документ предназначен для всех авторов модулей, он особенно ориентирован на авторов, желающих опубликовать свои модули на CPAN.
Основное внимание уделяется элементам стиля, которые видны пользователям модуля, а не тем частям, которые видят только разработчики модуля. Однако многие рекомендации, приведенные в этом документе, могут быть успешно экстраполированы и применены к внутренним частям модуля.
Данный документ отличается от perlnewmod тем, что это руководство по стилю, а не учебник по созданию модулей CPAN. Он предоставляет список проверок, с помощью которых можно сравнивать модули, чтобы определить, соответствуют ли они лучшей практике, не описывая подробно, как этого добиться.
Все советы, содержащиеся в этом документе, были получены из обширных бесед с опытными авторами и пользователями CPAN. Каждый совет здесь является результатом предыдущих ошибок. Эта информация поможет вам избежать тех же ошибок и дополнительных усилий, которые неизбежно потребуются для их исправления.
В первой части этого документа представлен список проверок, а в последующих частях содержится более подробное обсуждение пунктов этого списка. В заключительной части, "Общие ошибки", описаны некоторые из самых распространённых ошибок, которые допускают авторы CPAN.
БЫСТРЫЙ СПИСОК ПРОВЕРКИ
Для получения более подробной информации по каждому пункту этого списка см. ниже.
Перед началом
-
Не переизобретайте колесо
-
Если возможно, исправьте, расширьте или создайте подкласс существующего модуля
-
Делайте одно и делайте хорошо
-
Выберите подходящее имя
-
Получите обратную связь перед публикацией
API
-
API должен быть понятен среднему программисту
-
Простые методы для простых задач
-
Разделение функциональности от вывода
-
Согласованное именование подпрограмм или методов
-
Используйте именованные параметры (хэш или хэша) когда параметров больше, чем два
Стабильность
-
Убедитесь, что ваш модуль работает под
use strictи-w -
Стабильные модули должны поддерживать обратную совместимость
Документация
-
Напишите документацию в формате POD
-
Документируйте цель, область и целевые приложения
-
Документируйте каждый публичный доступный метод или подпрограмму, включая параметры и возвращаемые значения
-
Приведите примеры использования в своей документации
-
Предоставьте файл README и, возможно, заметки о выпуске, changelog и т. д.
-
Предоставьте ссылки на дополнительную информацию (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.) Дамиан Конвей предоставляет список критериев, которые нужно использовать при решении, подходит ли ООП для вашей задачи:
-
Разрабатываемая система большая или, вероятно, станет большой.
-
Данные можно агрегировать в очевидные структуры, особенно если в каждой агрегации много данных.
-
Различные типы агрегированных данных образуют естественную иерархию, что облегчает использование наследования и полиморфизма.
-
У вас есть данные, к которым применяются многие различные операции.
-
Вам нужно выполнять одни и те же общие операции над связанными типами данных, но с небольшими вариациями в зависимости от конкретного типа данных, к которому применяются операции.
-
Вероятно, вам придется добавлять новые типы данных позже.
-
Типичные взаимодействия между данными лучше всего представляются операторами.
-
Реализация отдельных компонентов системы, вероятно, со временем изменится.
-
Дизайн системы уже ориентирован на объекты.
-
Ваш код будут использовать большое количество других программистов.
Внимательно подумайте, подходит ли объектно-ориентированное программирование (ООП) для вашего модуля. Необоснованное применение ООП приводит к сложным 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);Предоставляйте разумные значения по умолчанию для параметров, которые их имеют. Не заставляйте пользователей указывать параметры, которые почти всегда будут одинаковыми.
Вопрос о том, следует ли передавать аргументы в хэше или в ссылках на хэш, в значительной степени зависит от личных предпочтений.
Использование ключей хэша, начинающихся с дефиса (
-name) или полностью в верхнем регистре (NAME) — это пережиток более ранних версий Perl, в которых обычные строчные строки не обрабатывались правильно оператором=>. Хотя некоторые модули сохраняют ключи аргументов в верхнем регистре или с дефисами по историческим причинам или по личным предпочтениям, большинство новых модулей должны использовать простые строчные ключи. Какой бы вариант вы ни выбрали, будьте последовательны!
Строгость и предупреждения
Ваш модуль должен успешно работать под прагмой strict и без генерации каких-либо предупреждений. Ваш модуль также должен обрабатывать проверку на загрязнение, когда это уместно, хотя это может вызвать трудности во многих случаях.
Обратная совместимость
Модули, которые являются «стабильными», не должны нарушать обратную совместимость без, по крайней мере, длительного переходного периода и существенного изменения номера версии.
Обработка ошибок и сообщений
Когда ваш модуль сталкивается с ошибкой, он должен сделать одно или несколько из следующего:
-
Возвратить неопределённое значение.
-
установить
$Module::errstrили аналогичное (errstr— распространенное имя, используемое DBI и другими популярными модулями; если вы выберете что-то другое, убедитесь, что это четко документировано). -
warn()илиcarp()сообщение в STDERR. -
croak()только тогда, когда ваш модуль абсолютно не может понять, что делать. (croak()— лучшая версияdie()для использования внутри модулей, которая сообщает об ошибках с точки зрения вызывающей стороны. См. Carp для получения подробностей оcroak(),carp()и других полезных подпрограммах.) -
В качестве альтернативы вышеперечисленному, вы можете предпочесть использовать исключения с помощью модуля Error.
Настраиваемая обработка ошибок может быть очень полезна для ваших пользователей. Подумайте о предоставлении выбора уровней предупреждений и отладочных сообщений, возможности отправки сообщений в отдельный файл, способа указания процедуры обработки ошибок или других подобных функций. Убедитесь, что все эти параметры по умолчанию установлены в наиболее часто используемом значении.
ДОКУМЕНТИРОВАНИЕ ВАШЕГО МОДУЛЯ
POD
Ваш модуль должен содержать документацию, предназначенную для разработчиков Perl. Вы должны использовать «простую старую документацию» (POD) Perl для вашей общей технической документации, хотя вы можете захотеть написать дополнительную документацию (белые книги, учебники и т. д.) в другом формате. Вам нужно охватить следующие темы:
-
Обзор распространенных способов использования модуля
-
Цель, область и целевые приложения вашего модуля
-
Использование каждого публично доступного метода или подпрограммы, включая параметры и возвращаемые значения
-
Примеры использования
-
Источники дополнительной информации
-
Адрес электронной почты автора/администратора
Уровень детализации в документации модуля Perl обычно варьируется от менее подробного к более подробному. Раздел SYNOPSIS должен содержать минимальный пример использования (возможно, всего одну строку кода; пропустите необычные случаи использования или то, что не нужно большинству пользователей); раздел DESCRIPTION должен описывать ваш модуль в общих чертах, обычно в нескольких абзацах; более подробная информация о подпрограммах или методах модуля, длинные примеры кода или другие подробные материалы должны быть приведены в последующих разделах.
В идеале, тот, кто немного знаком с вашим модулем, должен уметь освежить свои знания, не нажимая «страница вниз». По мере продвижения читателя по документу он должен получать все больше знаний.
Рекомендуемый порядок разделов в документации модуля 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 — это число с плавающей запятой с как минимум двумя цифрами после десятичной точки. Вы можете проверить, соответствует ли он CPAN, используя
perl -MExtUtils::MakeMaker -le 'print MM->parse_version(shift)' \
'Foo.pm' Если вы хотите выпустить «бета» или «альфа» версию модуля, но не хотите, чтобы CPAN.pm отображал её как последнюю, используйте «_» после обычного номера версии, за которым следуют как минимум две цифры, например, 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 для получения подробностей.
Тестирование
Все модули должны быть протестированы перед распространением (используя «make disttest»), а тесты также должны быть доступны пользователям, устанавливающим модули (используя «make test»). Для Module::Build вы бы использовали эквивалент make test %%%CODE_BLOCK_37%%.
Значимость этих тестов пропорциональна предполагаемой стабильности модуля. Модуль, который претендует на стабильность или который надеется на широкое использование, должен придерживаться максимально строгих правил тестирования.
Полезные модули для написания тестов (с минимальным влиянием на ваш процесс разработки или ваше время) включают 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 Authors Upload Server. Содержит ссылки на информацию для авторов модулей.
- Любая хорошая книга по программной инженерии
АВТОР
Kirrily «Skud» Robert <skud@cpan.org>
© 1993–2021 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.36.0/perlmodstyle