Перейти к содержанию

Некоторые сведения о Perl 5/POD

Материал из Викиучебника — открытых книг для открытого мира


Когда программа на языке Perl становится большой и полезной, разработчик начинает задумываться, как донести до пользователя информацию, как ей пользоваться. Традиционным средством документирования в Perl является разметка POD (от англ. Plain Old Documentation), которая позволяет встраивать документацию прямо в исходный файл. Далее исходный файл с документацией может быть обработан специальными утилитами, которые извлекают абзацы документации и сохраняют их в другой формат, более удобный для чтения, например, HTML, LaTeX или форматированные абзацы, которые могут быть выведены на терминальное устройство.

Разметка POD является очень простой (настолько же простой как и Markdown[1]) и освоить её вы сможете быстро. POD представляет собой блоки в исходном коде, которые локализуются управляющими словами. По этим словам интерпретатор Perl игнорирует их на этапе компиляции. Текст абзацев может быть записан в практически любой кодировке, но по умолчанию ожидается ASCII-US.

Нет какого-то единого стандарта оформления документации на Perl, однако, за много лет существования CPAN обычно документация любого модуля содержит следующие разделы[2]:

  • NAME — по сути является аннотацией к модулю. Обычно здесь приводится имя главного пакета модуля и одним-двумя предложениями записывается для чего он предназначен.
  • SYNOPSIS — обычно сюда записываются все основные функции модуля, возможно, с короткими примерами их вызовов.
  • DESCRIPTION — сюда записывается документация к модулю во всех подробностях.
  • OPTIONS — приводится перечень всех опций модуля.
  • EXAMPLES — приводятся некоторые общие примеры использования модуля.
  • AUTHOR — здесь приводятся авторы модуля, возможно с контактными данными.
  • COPYRIGHT — сюда приводится копирайт автора. Обычно публичные модули Perl распространяются под лицензией GPL, либо Artistic License.

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

Основы разметки POD

[править]

В POD имеется три сущности:

  • Простой параграф. Из этих параграфов состоит большая часть документации. Простые параграфы локализуются командными параграфами. Обычно транслятор разметки POD выполняет некоторые преобразования над такими параграфами, например, делает переносы слов, чтобы текст умещался в колонку (в типографическом смысле) определенной ширины. Простой параграф всегда должен начинаться с первой колонки, а также в нем могут использоваться коды форматирования.
  • Дословный параграф. Это частный случай простого параграфа, над которым транслятор разметки POD практически не выполняет никаких преобразований, в частности, сохраняется ширина строк, а все символы интерпретируются буквально. Чтобы транслятор начал интерпретировать параграф как дословный, нужно поставить один или более пробелов перед ним, либо поставить знак табуляции.
  • Командный параграф. Является управляющей конструкцией транслятора POD разметки.

Командные параграфы

[править]

Эти параграфы сообщают транслятору POD, что здесь нужно какое-то действие форматирования с его стороны. Форматирующие параграфы всегда начинаются с первой колонки документа и всегда начинаются символом =.

Ключевое слово Описание
=pod Сигнализирует о том, что с этой строки начинается блок POD разметки. Обычно не используется сам по себе, но используется в ситуациях, когда блок документации разрывается исходным кодом Perl.
=head[1-6] Текст заголовка Вводит заголовок раздела. Поддерживается 6 уровней вложенности заголовка[3]. После ключевого слова нужно записать текст заголовка. Заголовок может быть многострочным: чтобы транслятор понял, где заканчивается текст заголовка, нужно оставить после него пустую строку.
=over <отступ> Вводит одинаковый отступ для текстового блока. Размер отступа задается числом в параметре. Обычно используется для оформления списка. Граница действия отступа обозначается через =back. Если =over задается внутри другого, то отступ будет производится относительно предыдущего. Это используется для создания вложенности в списках.
=item <текст> Вводит блок пункта списка. Обычно в качестве параметра используется вводное слово, а в самом блоке записывается сам абзац. Ключевое слово действует до следующего элемента списка, либо до слова =back. Данное слово может использоваться исключительно между парой =over и =back.
=back Закрывает открытый ранее отступ =over. Количество =back должно быть равно количеству =over в тексте POD документации.
=begin <идентификатор формата>
=end <идентификатор формата>
Вводит абзац, который интерпретируется определенным транслятором. Чтобы транслятор знал, что этот блок для него, нужно записать идентификатор в параметре. Если некоторый транслятор не поддерживает идентификатор, то абзац будет полностью проигнорирован. Чтобы указать область действия этого абзаца, нужно использовать слово =end <идентификатор формата>. Идентификаторы в =begin и =end должны совпадать с точностью до символа.
=for <идентификатор формата> <параметры> Полностью аналогичен =begin и может использоваться как его синоним. Основная разница в том, что через него можно передавать особые параметры транслятору, если он их поддерживает.
=encoding <идентификатор кодировки> Определяет кодировку, в которой составлен POD текст. По умолчанию любой транслятор ожидает кодировку ASCII-US, и если нужно использовать символы регионального языка, вы должны указать кодировку явно. На странице Encode::Supported перечислены все кодировки, которые поддерживаются Perl из коробки. Данное ключевое слово должно быть использовано один раз в POD документации, другими словами, нельзя написать документацию разными кодировками.
=cut Указывает на конец действия параграфа POD-документации. Если не указан явно, то последний начатый POD-блок будет действовать до конца файла.
  • Важно помнить, что POD абзацы транслируются конкретным интерпретатором, поэтому к абзацам могут быть предъявлены особые требования. Обычно трансляторы следуют этой спецификации.
  • Вокруг командных параграфов следует всегда оставлять пустые строки, так как это помогает транслятору надежно их вычленять из исходного файла. Пустыми строками многие трансляторы считают такие, которые заполнены либо только переносом строки, либо переносом строки с пробелами и знаками табуляции.

Коды форматирования

[править]

В простых параграфах можно использовать коды форматирования для выделения текста в абзацах. Все они записываются по одной и той же схеме

[С]< [текст] >

[С]     - символ кода
<  >    - область действия
[текст] - выделяемый текст

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

C<<$a <=> $b>>
C<< $a <=> $b >>
C<<< $a <=> $b >>>
C<<<<  $a <=> $b     >>>>

Во всех случаях транслятор должен должен получить строку $a <=> $b. Пробелы между граничными угловыми скобками и внутренним текстом всегда игнорируются. До появления такого синтаксиса приходилось использовать громоздкий код экранирования E<>.

Ниже перечислены все поддерживаемые коды форматирования

Ключевое слово Описание Начертание
I<текст> Выводит текст в курсивном начертании. текст
B<текст> Выводит текст в полужирном начертании. текст
U<текст> Выводит текст в подчеркнутом начертании. текст
C<текст> Выводит текст в моноширинном начертании. текст
E<экранирование> Вводит экранирующий символ. Поддерживается несколько особых символов, очень похожих на HTML тэги.
E<lt> - символ 'меньше' - <
E<gt> - символ 'больше' - >
E<verbar> - символ вертикальной черты - |
E<sol> - символ косой черты - /
E<htmlname> - некоторые символы из разметки HTML
E<number> - символ из таблицы кодировки ASCII/Latin-1/Unicode, задаваемый кодом number.
F<file> Единообразно форматирует пути к файлам. file
S<текст c неразрывным пробелом> Запрещает транслятору переносы по пробелам в этом фрагменте.
X<заголовок для индекса> Некоторые трансляторы используют эту строку для заголовка в автоматически генерируемом индексе. Большинство трансляторов преобразуют эту строку в пустую строку.
Z<> Вводит фиктивный символ, который используется в очень особенных ситуациях, чтобы заставить транслятор делать отступы и сдвиги в ситуациях, в которых он их делать без печатаемого символа не должен.
L<текст> Используется для создания перекрестных ссылок документации.

Приемы форматирования документации

[править]

Вы можете видеть, что POD очень минималистичен и ориентирован на текстовые данные. Во многом это связано с тем, что раньше документацию выводили либо на терминал, который не умел выводить сложную графику, либо на принтер. Также POD изначально ориентируется на формат MAN-страниц — родной формат документации в Unix. Все, что сложнее текста, отдается на откуп трансляторам, которым передаются параграфы =begin.

Далее мы рассмотрим наиболее употребимые приемы форматирования текста. Мы будем также опираться на транслятор, преобразующий документацию в формат MAN.

Для примера мы будем документировать модуль, который выводит сообщение Hello World! на экран терминала.

Если файл хранит только POD-разметку

[править]

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

=head1 NAME

sayhello - Prints 'Hello World!' to anyone who asks for it.

=head1 SYNOPSIS

 print sayhello();
   
=head1 DESCRIPTION

This incredibly complex module is a top-secret development by ACME. It prints
C<Hello World!> securely and without delay. Our engineers spent
hours trying to figure out how to print this message.

In fact, we're wondering why we haven't received a prize for this module yet.

To start all the gears of our module, you only need to call the following procedure.

 sayhello();
   
B<Our module has the following features:>

=over 4

=item I<Thread safety>

Don't worry about deadlocks and such, because we're doing this in a single thread.

=item I<Speed>

In theory, if you're not trying to print text on your toaster, everything should
happen quickly.

=item I<And more ...>

=over 4

=item *Z<> We haven't decided what to write here yet.

The text has a left indent of 12 characters.

=back

=back

=head1 AUTHOR

John Doe

=head1 COPYRIGHT

Copyright (C) ACME Inc. All rights reserved.

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut

NAME
    sayhello - Prints 'Hello World!' to anyone who asks for it.

SYNOPSIS
     print sayhello();

DESCRIPTION
    This incredibly complex module is a top-secret development by ACME. It
    prints "Hello World!" securely and without delay. Our engineers spent
    hours trying to figure out how to print this message.

    In fact, we're wondering why we haven't received a prize for this module
    yet.

    To start all the gears of our module, you only need to call the
    following procedure.

     sayhello();

    Our module has the following features:

    *Thread safety*
        Don't worry about deadlocks and such, because we're doing this in a
        single thread.

    *Speed*
        In theory, if you're not trying to print text on your toaster,
        everything should happen quickly.

    *And more ...*

        * We haven't decided what to write here yet.
            The text has a left indent of 12 characters.

AUTHOR
    John Doe

COPYRIGHT
    Copyright (C) ACME Inc. All rights reserved.

    This library is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.
  • В примере выше сначала показана разметка на языке POD, а затем результат рендеринга на терминале xterm утилитой perldoc. К сожалению терминал не может выводить текст в полужирном начертании, а курсив обозначается звездочками вокруг слова.
  • Мы использовали символ Z<> во вложенном списке для того, чтобы пресечь вывод лишних пробелов после символа *.
  • Хотя наш файл записан только ASCII символами, на практике часто начинают файл документации строкой
    =encoding utf8
    так как современные системы повсеместно поддерживают Unicode.

Если документация размещается вместе с исходным кодом

[править]

Если мы составляем документацию вместе с исходным кодом, то мы можем вставлять абзацы POD везде, где вздумается. Обычно трансляторы проходятся по файлу сверху вниз, просто игнорируя код языка Perl. Однако, часть, которая не документирует непосредственно сам исходный код, лучше всего размещать за ключевым словом __END__, так как ожидается, что там будет размещена информация по использованию модуля (Usage Text).

Давайте теперь представим предыдущий пример вместе с исходным кодом.

=encoding utf8

=head1 FUNCTIONS

=cut

package HelloModule;

=head2 sayhello()

Returns "Hello World!".

=cut

sub sayhello() {
    return "Hello World!";
}

=pod

Comment for customers. In the future, we plan to improve the functionality.

=cut

1;

__END__

=head1 NAME

sayhello - Prints 'Hello World!' to anyone who asks for it.

=head1 SYNOPSIS

 print sayhello();
   
=head1 DESCRIPTION

This incredibly complex module is a top-secret development by ACME. It prints
C<Hello World!> securely and without delay. Our engineers spent
hours trying to figure out how to print this message.

In fact, we're wondering why we haven't received a prize for this module yet.

To start all the gears of our module, you only need to call the following procedure.

 sayhello();
   
B<Our module has the following features:>

=over 4

=item I<Thread safety>

Don't worry about deadlocks and such, because we're doing this in a single thread.

=item I<Speed>

In theory, if you're not trying to print text on your toaster, everything should
happen quickly.

=item I<And more ...>

=over 4

=item *Z<> We haven't decided what to write here yet.

The text has a left indent of 12 characters.

=back

=back

=head1 AUTHOR

John Doe

=head1 COPYRIGHT

Copyright (C) ACME Inc. All rights reserved.

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut

Если теперь попробовать также извлечь документацию из файла в формате MAN, то результат рендеринга будет таким.

FUNCTIONS
  sayhello()
    Returns "Hello World!".

    Comment for customers. In the future, we plan to improve the
    functionality.

NAME
    sayhello - Prints 'Hello World!' to anyone who asks for it.

SYNOPSIS
     print sayhello();

DESCRIPTION
    This incredibly complex module is a top-secret development by ACME. It
    prints "Hello World!" securely and without delay. Our engineers spent
    hours trying to figure out how to print this message.

    In fact, we're wondering why we haven't received a prize for this module
    yet.

    To start all the gears of our module, you only need to call the
    following procedure.

     sayhello();

    Our module has the following features:

    *Thread safety*
        Don't worry about deadlocks and such, because we're doing this in a
        single thread.

    *Speed*
        In theory, if you're not trying to print text on your toaster,
        everything should happen quickly.

    *And more ...*

        * We haven't decided what to write here yet.
            The text has a left indent of 12 characters.

AUTHOR
    John Doe

COPYRIGHT
    Copyright (C) ACME Inc. All rights reserved.

    This library is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.

Генерация Usage

[править]

Обычно стандартный дистрибутив Perl поставляется вместе с модулем Pod::Usage, который позволяет вам быстро генерировать Usage документацию из уже имеющейся в исходном файле. Этот модуль также используется утилитой pod2usage.

Ниже показан пример утилиты на языке Perl, в которой реализованы опции --help, --man и --describe, которые выводят разделы встроенной документации.

use strict;
use Getopt::Long qw(GetOptions);
use Pod::Usage qw(pod2usage);

my $man = 0;
my $help = 0;
my $description = 0;

GetOptions('help|?' => \$help, 'man' => \$man, 'describe' => \$description) or pod2usage(2);
pod2usage(1) if $help;
pod2usage(
    -verbose => 2,
    -exitval => 0
) if $man;

pod2usage(
    -verbose => 99,
    -sections => [ qw(DESCRIPTION) ],
    -exitval => 0
) if $description;

exit 0;

__END__

=head1 NAME

example - Demonstrate Pod::Usage.

=head1 SYNOPSIS

  example [options]

  Options:
   -help            brief help message
   -man             full documentation

=head1 OPTIONS

=over 4

=item B<-help>

Prints a brief help message and exits.

=item B<-man>

Prints the manual page and exits.

=back

=head1 DESCRIPTION

B<This program> will read the given input file(s) and do something
useful with the contents thereof.

=cut

В этом примере при вызове программы с опцией --help модуль Pod::Usage автоматически вернет разделы SYNOPSIS и OPTIONS. Такое поведение заложено при передаче значения 1 для опции -verbose. Соответственно чем больше это число, тем больше разделов документации выводится. По этой причине при вызове программы с опцией --man выводятся все разделы, так как там используется -verbose 2.

Для опции --describe мы используем значение 99. Это значение достаточно большое, чтобы вывести все что есть, однако, мы используем фильтр, по которому выводится только раздел DESCRIPTION. По умолчанию Pod::Usage выводит документацию и возвращает ненулевой код, однако в командной оболочке в случае успеха принято возвращать нулевой код. Для этого мы используем опцию -exitval. Подробнее о данном модуле вы сможете узнать из страницы документации Pod::Usage.

Ниже демонстрируются вызовы.

$ perl example.pl -h
Usage:
      example [options]

      Options:
       -help            brief help message
       -man             full documentation

Options:
    -help
        Prints a brief help message and exits.

    -man
        Prints the manual page and exits.

$ perl example.pl -unknown
Unknown option: unknown
Usage:
      example [options]

      Options:
       -help            brief help message
       -man             full documentation

$ perl example.pl -describe
Description:
    This program will read the given input file(s) and do something useful
    with the contents thereof.

$ perl example.pl -man
NAME
    example - Demonstrate Pod::Usage.

SYNOPSIS
      example [options]

      Options:
       -help            brief help message
       -man             full documentation

OPTIONS
    -help
        Prints a brief help message and exits.

    -man
        Prints the manual page and exits.

DESCRIPTION
    This program will read the given input file(s) and do something useful
    with the contents thereof.

Проблемы с кодировками

[править]

Если вы составляете документацию только на английском, никаких проблем обычно не возникает. Тем не менее, ваш модуль может быть мультиязычным, а документация к нему может встраиваться в систему с региональными настройками языка. Обычно в этих случаях разработчик заготавливает POD-файлы на различных языках.

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

Мы рассмотрим эту проблему для Unix и Unix-like систем с установленной locale. Если вы вызовете эту команду с опцией -a, то узнаете, какие локали поддерживаются данной конкретной системой. Например, вызов

$ locale -a
C
C.UTF-8
POSIX
ru_RU.utf8

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

$ locale
LANG=ru_RU.UTF-8
LANGUAGE=
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=

Мы видим, что используется локаль ru_RU.utf8. Чтобы узнать какой таблицей для кодирования символов она пользуется, нужно вызвать команду

$ locale -c charmap
LC_CTYPE
UTF-8

То есть в данной системе используется стандарт кодирования UTF-8.

Пусть у нас есть такой файл с документацией

=head1 ИМЯ

example - Это образец документации на русском языке.

=head1 СИНОПСИС

Раздел синопсиса.

=head1 ОПИСАНИЕ

Описание.

=head1 АВТОРЫ

Авторы.

=head1 ЛИЦЕНЗИЯ

Раздел с лицензией.

=cut

Если попытаться его открыть с помощью perldoc, то будет выведено предупреждение, но, тем не менее, он откроется правильно, потому что кодировка соответствует текущей локали:

ИМЯ
    example - Это образец документации на русском языке.

СИНОПСИС
    Раздел синопсиса.

ОПИСАНИЕ
    Описание.

АВТОРЫ
    Авторы.

ЛИЦЕНЗИЯ
    Раздел с лицензией.

POD ERRORS
    Hey! The above document had some coding errors, which are explained
    below:

    Around line 1:
        Non-ASCII character seen before =encoding in 'ИМЯ'. Assuming UTF-8

Предупреждение говорит о том, что файл начинается не с ASCII символа, но нас спасает то, что в таких случаях модуль Encode всегда использует UTF-8 по умолчанию. Чтобы эта ошибка пропала, нужно указать кодировку файла явно:

=encoding utf8

=head1 ИМЯ

example - Это образец документации на русском языке.

=head1 СИНОПСИС

Раздел синопсиса.

=head1 ОПИСАНИЕ

Описание.

=head1 АВТОРЫ

Авторы.

=head1 ЛИЦЕНЗИЯ

Раздел с лицензией.

=cut

Будьте внимательны к фактической кодировке файла и сохраняйте файлы правильно, иначе при расхождении значения =encoding с фактической кодировкой файла пользователь получит такой вывод

���
    example - ��� ������� ������������ �� ������� �����.

��������
    ������ ���������.

��������
    ��������.

������
    ������.

��������
    ������ � ���������.

другими словами, происходит неверное преобразование через карту символов текущей локали.

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

Утилиты для работы с POD разметкой

[править]

Утилита perldoc идет в стандартной поставке Perl и является основным инструментом просмотра POD-документации.

По умолчанию, если ей передать файл, то она попытается найти в нём POD и вывести его в формате MAN на терминал. Если передавать не файл, а имя пакета, либо некоторое слово, утилита попытается найти подходящую для этого POD-страницу, пользуясь общеизвестными путями размещения документации.

Кроме этого, утилита используется для просмотра документации по языку Perl. Для этого нужно использовать опции

perldoc -f <встроенная функция>
perldoc -q <FAQ>
perldoc -v <имя переменной>
perldoc -a <API>

К сожалению нет возможности узнать заранее, какие POD доступны для чтения прямо сейчас из общеизвестных директорий. Но существуют способы узнать это через вызовы специальных модулей, например модуля Pod::Simple::Search, который может просмотреть эти директории и вывести доступные вам ключевые слова. Ниже показана небольшая программа, которая выводит полный перечень доступных вам ключевых слов. Вывод команды может быть очень большой, поэтому рекомендуется делать вывод в файл, либо использовать команду оболочки less для просмотра результата.

#!/usr/bin/perl
# search.pl
use Pod::Simple::Search;
my $name2path = Pod::Simple::Search->new->limit_glob('*')->survey;
print "Results: ",
  join("\n", sort keys %$name2path), "\n";
$ search.pl | less

Results: Algorithm::Diff
Algorithm::Diff::XS
Algorithm::DiffOld
Algorithm::Merge
AnyDBM_File
App::Cpan
App::Prove
App::Prove::State
App::Prove::State::Result
App::Prove::State::Result::Test
Archive::Tar
Archive::Tar::File
Attribute::Handlers
......



$ perldoc App::Cpan
NAME
    App::Cpan - easily interact with CPAN from the command line

SYNOPSIS
            # with arguments and no switches, installs specified modules
            cpan module_name [ module_name ... ]

            # with switches, installs modules with extra behavior
            cpan [-cfFimtTw] module_name [ module_name ... ]

            # use local::lib
            cpan -I module_name [ module_name ... ]

            # one time mirror override for faster mirrors
            cpan -p ...

            # with just the dot, install from the distribution in the
            # current directory
            cpan .

            # without arguments, starts CPAN.pm shell
            cpan

            # without arguments, but some switches
            cpan [-ahpruvACDLOPX]

DESCRIPTION
    This script provides a command interface (not a shell) to CPAN. At the
    moment it uses CPAN.pm to do the work, but it is not a one-shot command
    runner for CPAN.pm.
.....................

pod2man / pod2text / pod2html / pod2latex

[править]

Если ваша документация не уходит дальше системы, то вам будет достаточно хранить её в POD формате. Однако, не всегда транслятор POD может быть под рукой, либо пользователю может быть неудобно использовать этот формат. На этот случай предусмотрены следующие стандартные конвертеры:

  • pod2man — преобразует POD в формат утилит семейства *roff, через которые генерируются MAN-страницы. MAN-страницы по умолчанию используются в *nix системах.
  • pod2text — преобразует POD в обычный форматированный текст, который может быть прочитан любым текстовым редактором.
  • pod2html — конвертирует POD в HTML. Может использоваться для генерации небольших сайтов, документирующих ваш большой проект, которые можно затем практически бесшовно разворачивать в сети.
  • pod2latex — конвертирует POD для системы верстки LaTeX.

Перечисленные утилиты не являются единственными. В CPAN можно найти и другие конвертеры, например, в тот же формат Markdown.

Отметим, что документацию по любой стандартной утилите вы также можете получить через perldoc:

$ perldoc pod2man

podchecker

[править]

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

podselect / pod2usage

[править]

Утилита pod2usage является консольной версией модуля Pod::Usage. Она позволяет автоматически формировать текст Usage из разделов документации, которые может найти в исходном файле. С помощью её опции -verbose вы можете управлять количеством разделов (как мы это делали в примере выше):

  • 0 — только SYNOPSIS;
  • 1 — SYNOPSIS и OPTIONS/ARGUMENTS;
  • 2 — выведет всё, что есть.
$ pod2usage -verbose 1 ./Usage.pl 
Usage:
      example [options]

      Options:
       -help            brief help message
       -man             full documentation

Options:
    -help
        Prints a brief help message and exits.

    -man
        Prints the manual page and exits.

Утилита podselect похожа на pod2usage, но она позволяет напечатать конкретный раздел документации:

$ podselect -section DESCRIPTION ./Usage.pl 
=head1 DESCRIPTION

B<This program> will read the given input file(s) and do something
useful with the contents thereof.

Обратите внимание, что печатается просто секция без какого-либо форматирования.

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

Интерпретатор командной оболочки Bash не узнает о документации, если отгородить её, например, вот так

#!/bin/bash
# sayhello.sh

echo "Hello, World"

exit 0

=encoding utf8

=head1 ИМЯ

sayhello.sh - Печатает строку C<Hello, World> на экране терминала.

=head1 СИНОПСИС

    /path/to/sayhello.sh

=head1 АВТОР

John Doe

=cut
$ ./sayhello.sh
Hello, World

$ pod2usage -verbose 3 ./sayhello.sh
ИМЯ
    sayhello.sh - Печатает строку "Hello, World" на экране терминала.

СИНОПСИС
        /path/to/sayhello.sh

АВТОР
    John Doe

POD-разметка могла бы быть размещена в исходном файле языка Си в многострочном комментарии.

// Файл: program.c
 
 int main(int argc, char** argv) {
    return 0;
 }

/*

=encoding utf8

=head1 DESCRIPTION

This program does nothing.

=cut
 
*/
$ perldoc ./program.c
DESCRIPTION
    This program does nothing.

Примечания

[править]
  1. Формат Markdown появился много позже POD, однако существуют преобразователи из POD в Markdown (см. Pod::Markdown).
  2. Следующая страница приводит некоторые принятые сообществом рекомендации по оформлению: Perl POD Style
  3. До 2020 года 5 и 6 уровни официально не поддерживались, поэтому очень старые трансляторы могут реагировать на них с ошибкой.