Spec-Zone.ru › Perl 5.28

perlhack

СОДЕРЖАНИЕ

  • NAME
  • DESCRIPTION
  • СУПЕР БЫСТРОЕ РУКОВОДСТВО ПО НАЛОЖЕНИЮ ПАТЧЕЙ
  • СООБЩЕНИЕ ОБ ОШИБКАХ
  • РАЗРАБОТЧИКИ PERL 5
    • Рассылка perl-changes
    • #p5p на IRC
  • ПОЛУЧЕНИЕ ИСТОЧНОГО КОДА PERL
    • Чтение через Git
    • Чтение через веб
    • Чтение через rsync
    • Запись через git
  • НАЛОЖЕНИЕ ПАТЧЕЙ НА PERL
    • Отправка патчей
    • Получение одобрения патча
      • Стиль патча
      • Сообщение о коммите
      • Комментарии, комментарии, комментарии
      • Стиль
      • Набор тестов
    • Наложение патча на основной модуль
    • Обновление perldelta
    • Что делает патч хорошим?
      • Соответствует ли концепция общим целям Perl?
      • Где реализация?
      • Обратная совместимость
      • Можно ли сделать это модулем?
      • Достаточно ли универсальна функция?
      • Может ли это привести к новым ошибкам?
      • Насколько он большой?
      • Исключает ли он другие желательные функции?
      • Надежна ли реализация?
      • Достаточно ли универсальна реализация для переносимости?
      • Протестирована ли реализация?
      • Достаточно ли документации?
      • Есть ли другой способ сделать это?
      • Создает ли это слишком много работы?
      • Патчи говорят громче слов
  • ТЕСТИРОВАНИЕ
    • Специальные цели make test
    • Параллельные тесты
    • Запуск тестов вручную
    • Использование t/harness для тестирования
      • Другие переменные среды, которые могут влиять на тесты
    • Тестирование производительности
    • Сборка perl на более старых коммитах
  • ДОПОЛНИТЕЛЬНАЯ ЛИТЕРАТУРА ДЛЯ ПРОГРАММИСТОВ
  • ТЕСТЕРЫ CPAN И ТЕСТЕРЫ PERL
  • ЧТО ДАЛЬШЕ?
    • "Дорога тянется всё дальше и дальше, вниз от двери, где она начиналась."
    • Метафорические цитаты
  • АВТОР

NAME

perlhack - Как работать над Perl

DESCRIPTION

Этот документ объясняет, как работает разработка Perl. Он включает в себя подробную информацию о списке рассылки Perl 5 Porters, репозитории Perl, системе отслеживания ошибок Perlbug, рекомендациях по патчам и комментариях к философии разработки Perl.

СУПЕР БЫСТРОЕ РУКОВОДСТВО ПО НАЛОЖЕНИЮ ПАТЧЕЙ

Если вы просто хотите отправить один небольшой патч, например, исправление pod, тест для ошибки, исправление комментариев и т. д., это легко! Вот как:

  • Проверьте репозиторий исходного кода

    Исходный код perl находится в репозитории git. Вы можете клонировать репозиторий с помощью следующей команды:

    % git clone git://perl5.git.perl.org/perl.git perl
  • Убедитесь, что вы следуете последним рекомендациям

    В случае, если рекомендации в этом руководстве были недавно обновлены, прочитайте последнюю версию непосредственно из исходного кода perl:

    % perldoc pod/perlhack.pod
  • Внесите изменения

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

  • Протестируйте ваши изменения

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

    % ./Configure -des -Dusedevel
    % make test

    Продолжайте работать, пока тесты не пройдут.

  • Зафиксируйте изменения

    Фиксация вашей работы сохранит изменения в вашей локальной системе:

    % git commit -a -m 'Commit message goes here'

    Убедитесь, что сообщение о фиксации описывает ваши изменения в одном предложении. Например, "Исправлены орфографические ошибки в perlhack.pod".

  • Отправьте изменения в perlbug

    Следующим шагом является отправка вашего патча в систему отслеживания ошибок Perl core по электронной почте.

    Если ваши изменения находятся в одном коммите git, выполните следующие команды, чтобы сгенерировать файл патча и прикрепить его к вашему отчету об ошибке:

    % git format-patch -1
    % ./perl -Ilib utils/perlbug -p 0001-*.patch

    Программа perlbug задаст вам несколько вопросов о вашем адресе электронной почты и отправляемом патче. После того, как вы ответите на них, он отправит ваш патч по электронной почте.

    Если ваши изменения находятся в нескольких коммитах, сгенерируйте файл патча для каждого из них и предоставьте их параметру -p perlbug, разделенному запятыми:

    % git format-patch -3
    % ./perl -Ilib utils/perlbug -p 0001-fix1.patch,0002-fix2.patch,\
    > 0003-fix3.patch

    При появлении запроса выберите тему, которая суммирует ваши изменения.

  • Спасибо

    Разработчики ценят время, которое вы потратили на улучшение Perl. Спасибо!

  • Благодарность

    Все участники указаны (по имени и адресу электронной почты) в файле AUTHORS, который является частью дистрибутива perl, а также в истории коммитов Git.

    Если вы не хотите, чтобы вас включали в файл AUTHORS, просто дайте нам знать. В противном случае мы будем считать вашу отправку патча разрешением на указание вас в файле AUTHORS.

  • В следующий раз

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

    % git pull
    % git reset --hard origin/blead
    % git clean -dxf

СООБЩЕНИЕ ОБ ОШИБКАХ

Если вы хотите сообщить об ошибке в Perl, вы должны использовать командную строку perlbug. Этот инструмент гарантирует, что ваш отчет об ошибке будет содержать всю необходимую информацию о системе и конфигурации.

Чтобы просмотреть существующие ошибки и патчи Perl, вы можете использовать веб-интерфейс по адресу http://rt.perl.org/.

Пожалуйста, проверьте архив списка perl5-porters (см. ниже) и/или систему отслеживания ошибок перед отправкой отчета об ошибке. Часто вы обнаружите, что ошибка уже была зарегистрирована.

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

РАЗРАБОТЧИКИ PERL 5

Список рассылки perl5-porters (p5p) — это место, где поддерживается и разрабатывается стандартный дистрибутив Perl. Люди, которые поддерживают Perl, также называются «Perl 5 Porters», «p5p» или просто «разработчиками».

Поисковый архив списка доступен по адресу http://markmail.org/search/?q=perl5-porters. Также существует архив по адресу http://archive.develooper.com/perl5-porters@perl.org/.

Рассылка perl-changes

Список рассылки perl5-changes получает копию каждого патча, который отправляется в ветки обслуживания и разработки репозитория perl. См. http://lists.perl.org/list/perl5-changes.html для получения информации о подписке и архиве.

#p5p на IRC

Многие разработчики также активны на канале irc://irc.perl.org/#p5p. Не стесняйтесь присоединяться к каналу и задавать вопросы о работе над ядром Perl.

ПОЛУЧЕНИЕ ИСТОЧНОГО КОДА PERL

Весь исходный код Perl хранится централизованно в репозитории Git по адресу perl5.git.perl.org. Репозиторий содержит множество ревизий Perl, начиная с Perl 1, и все ревизии из Perforce, предыдущей системы контроля версий.

Для получения более подробной информации об использовании git с репозиторием Perl, пожалуйста, см. perlgit.

Чтение через Git

Вам понадобится копия Git для вашего компьютера. Вы можете получить копию репозитория, используя протокол git:

% git clone git://perl5.git.perl.org/perl.git perl

Это клонирует репозиторий и создает локальную копию в каталоге perl.

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

% git clone http://perl5.git.perl.org/perl.git perl

Чтение через веб

Вы можете получить доступ к репозиторию через веб-интерфейс. Это позволяет вам просматривать древовидную структуру, видеть последние коммиты, подписываться на RSS-ленты для отслеживания изменений, искать определенные коммиты и многое другое. Вы можете получить к нему доступ по адресу http://perl5.git.perl.org/perl.git. Зеркало репозитория находится по адресу https://github.com/Perl/perl5.

Чтение через rsync

Вы также можете использовать rsync для получения копии текущего исходного дерева для ветки bleadperl и всех веток обслуживания:

% rsync -avz rsync://perl5.git.perl.org/perl-current .
% rsync -avz rsync://perl5.git.perl.org/perl-5.12.x .
% rsync -avz rsync://perl5.git.perl.org/perl-5.10.x .
% rsync -avz rsync://perl5.git.perl.org/perl-5.8.x .
% rsync -avz rsync://perl5.git.perl.org/perl-5.6.x .
% rsync -avz rsync://perl5.git.perl.org/perl-5.005xx .

(Добавьте опцию --delete для удаления оставшихся файлов.)

Чтобы получить полный список доступных точек синхронизации:

% rsync perl5.git.perl.org::

Запись через git

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

ВНЕСЕНИЕ ИЗМЕНЕНИЙ В PERL

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

Отправка исправлений

Если у вас есть небольшое исправление для отправки, пожалуйста, отправьте его через perlbug. Вы также можете отправить электронное письмо непосредственно на perlbug@perl.org. Обратите внимание, что сообщения, отправленные в perlbug, могут храниться в очереди модерации, поэтому вы не получите немедленного ответа.

Вы узнаете, что ваша заявка обработана, когда получите электронное письмо от нашей системы отслеживания тикетов. Это электронное письмо даст вам номер тикета. После того, как ваше исправление попадет в систему отслеживания тикетов, оно также будет отправлено в список perl5-porters@perl.org.

Если ваше исправление связано с уже открытым тикетом, вы также можете прикрепить свое исправление к этому тикету, не используя perlbug.

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

В других случаях исправление потребует дополнительной работы или обсуждения. Это произойдет в списке p5p.

Вам предлагается участвовать в обсуждении и отстаивать свое исправление. Иногда ваше исправление может затеряться. Целесообразно отправить напоминание на p5p, если в течение месяца не было предпринято никаких действий. Пожалуйста, помните, что разработчики Perl 5 — это волонтеры, и будьте вежливы.

Изменения всегда применяются непосредственно к основной ветке разработки, называемой "blead". Некоторые исправления могут быть перенесены в ветку обслуживания. Если вы считаете, что ваше исправление подходит для ветки обслуживания (см. "ВЕТКИ ОБСЛУЖИВАНИЯ" в perlpolicy), пожалуйста, объясните почему, когда вы отправите его.

Получение принятия вашего исправления

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

Стиль исправления

Если вы использовали git для извлечения исходного кода Perl, то использование git format-patch создаст исправление в стиле, подходящем для Perl. Команда format-patch создает один файл исправления для каждого сделанного вами коммита. Если вы предпочитаете отправлять один патч для всех коммитов, вы можете использовать git diff.

% git checkout blead
% git pull
% git diff blead my-branch-name

Это создает патч на основе разницы между blead и вашей текущей веткой. Важно убедиться, что blead обновлен перед созданием diff, поэтому мы сначала вызываем git pull.

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

Однако, если вы не используете git, вы все равно можете создать подходящий патч. Вам понадобится чистая копия исходного кода Perl для сравнения. Разработчики предпочитают унифицированные diff. Используя GNU diff, вы можете создать diff, например:

% diff -Npurd perl.pristine perl.mine

Убедитесь, что вы make realclean в вашей копии Perl, чтобы удалить все артефакты сборки, иначе вы можете получить запутанный результат.

Сообщение о коммите

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

Первая строка сообщения о коммите должна быть кратким описанием без точки. Она не должна быть длиннее темы электронного письма, 50 символов — хорошее эмпирическое правило.

Многие инструменты Git (Gitweb, GitHub, git log --pretty=oneline, ...) будут отображать только первую строку (обрезанную до 50 символов) при представлении сводок коммитов.

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

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

  • Почему

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

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

  • Что

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

  • Как

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

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

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

Комментарии, комментарии, комментарии

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

Лучшие комментарии объясняют, почему код делает то, что он делает, а не что он делает.

Стиль

В общем, пожалуйста, следуйте конкретному стилю кода, который вы исправляет.

В частности, следуйте этим общим рекомендациям для исправления исходных кодов Perl:

  • Отступы шириной в 4 символа для кода, отступы шириной в 2 символа для вложенных CPP #defines, с табуляцией шириной в 8 символов.

  • Используйте пробелы для отступов, а не символы табуляции.

    База кода представляет собой смесь табуляции и пробелов для отступов, и мы переходим только к пробелам. Преобразование строк, которые вы исправляет, из табуляции шириной 8 символов в пробелы, поможет этой миграции.

  • Старайтесь не превышать 79 столбцов

  • Прототипы ANSI C

  • Несжатые else и стиль "K&R" для отступа управляющих конструкций

  • Нет комментариев в стиле C++ (//)

  • Помечайте места, которые нужно пересмотреть, с помощью XXX (и пересматривайте часто!)

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

  • В определениях функций имя начинается в столбце 0 (тип возвращаемого значения находится на предыдущей строке)

  • Один пробел после ключевых слов, за которыми следуют круглые скобки, без пробела между именем функции и следующей круглой скобкой

  • Избегайте присваиваний в условиях, но если они неизбежны, используйте дополнительные круглые скобки, например "if (a && (b = c)) ..."

  • "return foo;" вместо "return(foo);"

  • "if (!foo) ..." вместо "if (foo == FALSE) ..." и т.д.

  • Не объявляйте переменные с помощью "register". Это может быть контрпродуктивно с современными компиляторами и устарело в C++, под которым исходный код Perl регулярно компилируется.

  • Встроенные функции, которые находятся в заголовках, доступных для кода XS, должны иметь возможность компилироваться без предупреждений с часто используемыми дополнительными флагами компиляции, такими как -Wswitch-default gcc, который выдает предупреждение, когда оператор switch не имеет случая "default". Использование этих дополнительных флагов предназначено для обнаружения потенциальных проблем в легальном коде C и часто используется агрегаторами Perl, такими как дистрибутивы Linux.

Тестовый набор

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

Ваши дополнения к тестовому набору должны, как правило, соответствовать следующим рекомендациям (благодаря Gurusamy Sarathy <gsar@activestate.com>):

  • Знайте, что вы тестируете. Прочитайте документацию и исходный код.

  • Стремитесь к неудаче, а не к успеху.

  • Строго интерпретируйте результаты.

  • Используйте несвязанные функции (это выявит странные взаимодействия).

  • Используйте нестандартные идиомы (в противном случае вы не тестируете TIMTOWTDI).

  • По возможности избегайте использования жестко закодированных тестовых чисел (EXPECTED/GOT, найденный в t/op/tie.t, гораздо проще в обслуживании и обеспечивает лучшие отчеты об ошибках).

  • Выдавайте содержательные сообщения об ошибках при сбое теста.

  • Избегайте использования qx// и system(), если вы не тестируете их. Если вы используете их, убедитесь, что вы охватываете _все_ платформы perl.

  • Удаляйте все созданные временные файлы.

  • Превращайте непредвиденные предупреждения в ошибки с помощью $SIG{__WARN__}.

  • Обязательно используйте библиотеки и модули, поставляемые с тестируемой версией, а не те, которые уже были установлены.

  • Добавьте комментарии к коду, объясняющие, что вы тестируете.

  • Сделайте обновление строки '1..42' ненужным. Или убедитесь, что вы обновили её.

  • Тестируйте _все_ поведения данного оператора, библиотеки или функции.

    Тестируйте все необязательные аргументы.

    Тестируйте возвращаемые значения в различных контекстах (булевы, скалярные, списки, lvalue).

    Используйте как глобальные, так и лексические переменные.

    Не забывайте об исключительных, патологических случаях.

Исправление основного модуля

Это работает так же, как и исправление чего-либо еще, с одним дополнительным моментом.

Модули в каталоге cpan/ исходного дерева поддерживаются за пределами ядра Perl. Когда автор обновляет модуль, обновления просто копируются в ядро. См. документацию этого модуля или его список на http://search.cpan.org/ для получения дополнительной информации об сообщениях об ошибках и отправке исправлений.

В большинстве случаев исправления модулей в cpan/ следует отправлять разработчикам и не применять их к ядру Perl по отдельности. Если исправление файла в cpan/ абсолютно нельзя ждать, пока исправление будет внесено разработчиками, выпущено в CPAN и скопировано в blead, необходимо добавить (или обновить) запись CUSTOMIZED в файле "Porting/Maintainers.pl", чтобы отметить, что внесены локальные изменения. Более подробная информация приведена в файле "Porting/Maintainers.pl".

В отличие от этого, модули в каталоге dist/ поддерживаются в ядре.

Обновление perldelta

Для изменений, достаточно значительных, чтобы гарантировать запись в pod/perldelta.pod, разработчики будут очень признательны, если вы отправите запись delta вместе с вашим фактическим изменением. К значительным изменениям относятся, помимо прочего:

  • Добавление, снятие с поддержки или удаление основных функций

  • Добавление, снятие с поддержки, удаление или обновление основных или двойных модулей

  • Добавление новых основных тестов

  • Исправление проблем безопасности и видимых пользователями ошибок в ядре

  • Изменения, которые могут нарушить существующий код, как на уровне perl, так и на уровне C

  • Значительные улучшения производительности

  • Добавление, удаление или значительное изменение документации в каталоге pod/

  • Важные изменения, зависящие от платформы

Пожалуйста, убедитесь, что вы добавили запись perldelta в правильный раздел в pod/perldelta.pod. Более подробная информация о том, как писать качественные записи perldelta, доступна в разделе Style файла Porting/how_to_write_a_perldelta.pod.

Что делает исправление хорошим?

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

Соответствует ли концепция общим целям Perl?

Наши цели включают, помимо прочего:

  1. Быстро, просто и полезно.

  2. Поддерживать функции/концепции как можно более ортогональными.

  3. Отсутствие произвольных ограничений (платформы, размеры данных, культуры).

  4. Поддерживать его открытым и захватывающим для использования/исправления/пропаганды Perl повсюду.

  5. Ассимилировать новые технологии или строить мосты к ним.

Где реализация?

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

Обратная совместимость

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

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

Можно ли вместо этого сделать модуль?

Perl 5 имеет механизмы расширения, модули и XS, специально для того, чтобы избежать необходимости постоянно изменять интерпретатор Perl. Вы можете писать модули, которые экспортируют функции, вы можете давать этим функциям прототипы, чтобы их можно было вызывать как встроенные функции, вы даже можете писать код XS, чтобы возиться со структурами данных времени выполнения интерпретатора Perl, если вы хотите реализовать действительно сложные вещи.

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

Достаточно ли универсальна функция?

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

Может ли это привести к новым ошибкам?

Радикальная переработка больших фрагментов интерпретатора Perl может привести к появлению новых ошибок.

Насколько это велико?

Чем меньше и более локализовано изменение, тем лучше. Аналогично, серия небольших исправлений намного предпочтительнее одного большого исправления.

Препятствует ли это другим желательным функциям?

Исправление, скорее всего, будет отклонено, если оно закроет будущие пути развития. Например, исправление, которое дало бы истинную и окончательную интерпретацию прототипов, скорее всего, будет отклонено, потому что все еще есть варианты для будущего прототипов, которые не были рассмотрены.

Надежна ли реализация?

Хорошие исправления (компактный код, полный, правильный) имеют больше шансов быть принятыми. Небрежные или неправильные исправления могут быть отложены до тех пор, пока у разработчика не будет времени их исправить, или могут быть полностью отброшены без дальнейшего уведомления.

Достаточно ли универсальна реализация для обеспечения переносимости?

Худшие исправления используют функции, зависящие от системы. Весьма маловероятно, что непереносимые дополнения к языку Perl будут приняты.

Протестирована ли реализация?

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

Без тестов, предоставленных оригинальным автором, как кто-либо еще, изменяющий perl в будущем, может быть уверен, что он невольно не сломал поведение, реализованное исправлением? И без тестов, как автор исправления может быть уверен, что его/ее тяжелая работа, вложенная в исправление, не будет случайно выброшена кем-то в будущем?

Достаточно ли документации?

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

Есть ли другой способ сделать это?

Ларри сказал: «Хотя слоган Perl — There's More Than One Way to Do It, я не решаюсь сделать 10 способов сделать что-то». Однако это сложный эвристический метод навигации — то, что один человек считает существенным дополнением, другой считает бессмысленным хламом.

Создает ли это слишком много работы?

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

Исправления говорят громче слов

Рабочий код всегда предпочтительнее идей из области фантастики. Исправление для добавления функции имеет гораздо больше шансов попасть в язык, чем случайный запрос функции, независимо от того, насколько горячо этот запрос может быть аргументирован. Это связано с вопросом «Будет ли это полезно?», поскольку тот факт, что кто-то потратил время на создание исправления, демонстрирует сильное желание получить эту функцию.

ТЕСТИРОВАНИЕ

Ядро использует тот же стиль тестирования, что и остальная часть Perl, простой прогон "ok/not ok" через Test::Harness, но есть несколько особых моментов.

Есть три способа написать тест в ядре: Test::More, t/test.pl и ad hoc print $test ? "ok 42\n" : "not ok 42\n". Решение о том, какой из них использовать, зависит от того, над какой частью тестового набора вы работаете. Это мера для предотвращения сбоя высокого уровня (например, сбоя Config.pm) от вызова сбоя тестов базовой функциональности.

Библиотека t/test.pl предоставляет некоторые функции Test::More, но избегает загрузки большинства модулей и использует как можно меньше основных функций.

Если вы пишете свой собственный тест, используйте Test Anything Protocol.

  • t/base, t/comp и t/opbasic

    Поскольку мы не знаем, работает ли require, или даже подпрограммы, используйте для этих трех ad hoc тесты. Действуйте осторожно, чтобы избежать использования тестируемой функции. Например, тесты в t/opbasic были помещены туда, а не в t/op, потому что они тестируют функциональность, которую t/test.pl предполагает, что уже была продемонстрирована как работающая.

  • t/cmd, t/run, t/io и t/op

    Теперь, когда базовые require() и подпрограммы протестированы, вы можете использовать библиотеку t/test.pl.

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

  • Все остальное

    Теперь, когда ядро Perl протестировано, Test::More можно и следует использовать. Вы также можете использовать полный набор основных модулей в тестах.

Когда вы говорите «make test», Perl использует программу t/TEST для запуска тестового набора (за исключением Win32, где вместо этого используется t/harness). Все тесты запускаются из каталога t/, не из каталога, содержащего тест. Это вызывает некоторые проблемы с тестами в lib/, поэтому здесь есть возможность для некоторых исправлений.

Вы должны быть втройне внимательны к проблемам кроссплатформенности. Обычно это сводится к использованию File::Spec, избеганию таких вещей, как fork() и system(), если это абсолютно необходимо, и не предполагая, что данный символ имеет определенное порядковое значение (код точки) или что его представление UTF-8 состоит из определенных байтов.

Существует несколько функций, доступных для указания символов и кодовых точек переносимым способом в тестах. Всегда предварительно загруженные функции utf8::unicode_to_native() и ее обратная utf8::native_to_unicode() принимают кодовые точки и переводят соответствующим образом. Файл t/charset_tools.pl содержит несколько полезных функций. Он содержит версии двух предыдущих функций, которые принимают строки в качестве входных данных — не отдельные числовые кодовые точки: uni_to_native() и native_to_uni(). Если вы должны посмотреть на отдельные байты, составляющие строку с кодировкой UTF-8, byte_utf8a_to_utf8n() принимает в качестве входных данных строку этих байтов, закодированных для платформы ASCII, и возвращает эквивалентную строку на собственной платформе. Например, byte_utf8a_to_utf8n("\xC2\xA0") возвращает последовательность байтов на текущей платформе, которые образуют UTF-8 для U+00A0, поскольку "\xC2\xA0" являются байтами UTF-8 на платформе ASCII для этой кодовой точки. Эта функция возвращает "\xC2\xA0" на платформе ASCII и "\x80\x41" на платформе EBCDIC 1047.

Но проще всего, если символ можно указать как литерал, например "A" или "%", использовать его; если нет, вы можете использовать \N{}, если побочные эффекты не являются проблематичными. Просто укажите все ваши символы в шестнадцатеричном формате, используя \N{U+ZZ} вместо \xZZ. \N{} — это имя Unicode, поэтому оно всегда дает вам символ Unicode. \N{U+41} — это символ, чья кодовая точка Unicode равна 0x41, следовательно, это 'A' на всех платформах. Побочные эффекты следующие:

  • Эти правила выбирают кодировку Юникод. Это означает, что в строках, заключенных в двойные кавычки, строка всегда преобразуется в UTF-8 для принудительного интерпретации Юникода (вы можете utf8::downgrade() после этого, чтобы преобразовать обратно в не-UTF8, если это возможно). В шаблонах регулярных выражений преобразование не выполняется, но если модификатор набора символов в противном случае будет /d, он изменяется на /u.

  • Если вы используете форму \N{character name}, модуль charnames загружается автоматически. Это может быть неподходящим для уровня тестирования, который вы проводите.

Если вы тестируете локали (см. perllocale), в t/loc_tools.pl есть вспомогательные функции, которые позволяют вам видеть, какие локали есть на текущей платформе.

Специальные цели make test

Существуют различные специальные цели make, которые можно использовать для тестирования Perl немного иначе, чем стандартная цель "test". Не все они должны давать 100% -ный результат. Многие из них имеют несколько псевдонимов, и многие из них недоступны в некоторых операционных системах.

  • test_porting

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

  • minitest

    Запускает miniperl на тестах t/base, t/comp, t/cmd, t/run, t/io, t/op, t/uni и t/mro.

  • test.valgrind check.valgrind

    (Только в Linux) Запускает все тесты с помощью инструмента для обнаружения утечек памяти и некорректного доступа к памяти "valgrind". Файлы журналов будут называться testname.valgrind.

  • test_harness

    Запускает набор тестов с помощью управляющей программы t/harness вместо t/TEST. t/harness более сложен и использует модуль Test::Harness, поэтому использование этой цели предполагает, что perl в основном работает. Главное преимущество для наших целей заключается в том, что он выводит подробное резюме неудачных тестов в конце. Кроме того, в отличие от t/TEST, он не перенаправляет stderr в stdout.

    Обратите внимание, что под Win32 t/harness всегда используется вместо t/TEST, поэтому специальной цели "test_harness" нет.

    Под целевым объектом "test" в Win32 вы можете использовать переменные среды TEST_SWITCHES и TEST_FILES для управления поведением t/harness. Это означает, что вы можете сказать

    nmake test TEST_FILES="op/*.t"
    nmake test TEST_SWITCHES="-torture" TEST_FILES="op/*.t"
  • test-notty test_notty

    Устанавливает PERL_SKIP_TTY_TEST в true перед запуском обычного теста.

Параллельные тесты

Основное дистрибутив теперь может запускать свои регрессионные тесты параллельно на платформах, подобных Unix. Вместо запуска make test, установите TEST_JOBS в вашей среде на количество тестов для параллельного запуска и запустите make test_harness. В оболочке типа Bourne это можно сделать так

TEST_JOBS=3 make test_harness  # Run 3 tests in parallel

Переменная среды используется вместо самого параллельного make, потому что TAP::Harness должен иметь возможность самостоятельно планировать отдельные неконфликтующие тестовые скрипты, и нет стандартного интерфейса для make утилит для взаимодействия с их планировщиками заданий.

Обратите внимание, что в настоящее время некоторые тестовые скрипты могут завершиться ошибкой при параллельном запуске (в первую очередь dist/IO/t/io_dir.t). При необходимости запустите снова только неудачные скрипты последовательно и посмотрите, исчезнут ли ошибки.

Запуск тестов вручную

Вы можете запустить часть набора тестов вручную, используя одну из следующих команд из каталога t/:

./perl -I../lib TEST list-of-.t-files

или

./perl -I../lib harness list-of-.t-files

(Если вы не указываете тестовые скрипты, будет запущен весь набор тестов.)

Использование t/harness для тестирования

Если вы используете harness для тестирования, у вас есть несколько доступных параметров командной строки. Аргументы следующие, и они должны появляться в том порядке, в котором они должны использоваться вместе.

harness -v -torture -re=pattern LIST OF FILES TO TEST
harness -v -torture -re LIST OF PATTERNS TO MATCH

Если LIST OF FILES TO TEST опущен, список файлов получается из манифеста. Список файлов может включать подстановочные знаки оболочки, которые будут развернуты.

  • -v

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

  • -torture

    Запускает тесты на стресс-тестирование, а также обычный набор.

  • -re=PATTERN

    Фильтровать список файлов так, чтобы все запускаемые тестовые файлы соответствовали PATTERN. Обратите внимание, что эта форма отличается от формы -re СПИСОК ШАБЛОНОВ ниже тем, что она позволяет также указать список файлов.

  • -re СПИСОК ШАБЛОНОВ

    Фильтровать список файлов так, чтобы все запускаемые тестовые файлы соответствовали /(LIST|OF|PATTERNS)/. Обратите внимание, что в этой форме шаблоны соединяются с помощью '|' и вы не можете указать список файлов, вместо этого тестовые файлы получаются из MANIFEST.

Вы можете запустить отдельный тест с помощью команды, подобной

./perl -I../lib path/to/foo.t

за исключением того, что оснастки устанавливают некоторые переменные среды, которые могут повлиять на выполнение теста:

  • PERL_CORE=1

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

  • PERL_DESTRUCT_LEVEL=2

    устанавливается в 2, если он еще не установлен (см. "PERL_DESTRUCT_LEVEL" в perlhacktips).

  • PERL

    (используется только t/TEST) если установлен, переопределяет путь к исполняемому файлу perl, который должен использоваться для запуска тестов (по умолчанию ./perl).

  • PERL_SKIP_TTY_TEST

    если установлен, указывает пропустить тесты, которым нужен терминал. На самом деле он устанавливается автоматически Makefile, но его также можно принудительно установить искусственно, запустив 'make test_notty'.

Другие переменные среды, которые могут влиять на тесты

  • PERL_TEST_Net_Ping

    Установка этой переменной запускает все тесты модулей Net::Ping, в противном случае некоторые тесты, которые взаимодействуют с внешним миром, пропускаются. См. perl58delta.

  • PERL_TEST_NOVREXX

    Установка этой переменной пропускает тесты vrexx.t для OS2::REXX.

  • PERL_TEST_NUMCONVERTS

    Это устанавливает переменную в op/numconvert.t.

  • PERL_TEST_MEMORY

    Установка этой переменной включает тесты в t/bigmem/. Она должна быть установлена в количество гигабайт памяти, доступной для тестирования, например, PERL_TEST_MEMORY=4 указывает, что тесты, требующие 4 ГБ доступной памяти, могут быть запущены безопасно.

См. также документацию по модулям Test и Test::Harness для получения дополнительной информации о переменных среды, которые влияют на тестирование.

Тестирование производительности

Файл t/perf/benchmarks содержит фрагменты кода perl, которые предназначены для бенчмаркинга на ряде версий perl с помощью инструмента Porting/bench.pl. Если вы исправляете или улучшаете проблему производительности, вы можете добавить репрезентативный образец кода в файл, а затем запустить bench.pl для предыдущих и текущих версий perl, чтобы увидеть, какую разницу это внесло и замедлилось ли что-либо еще в результате.

Файл t/perf/opcount.t предназначен для проверки того, был ли определенный фрагмент кода скомпилирован в optree, содержащий указанное количество определенных типов операций. Это хорошо подходит для проверки того, действительно ли оптимизации, которые изменяют операции, такие как преобразование операции aelem в операцию aelemfast, действительно делают это.

Файлы t/perf/speed.t и t/re/speed.t предназначены для тестирования вещей, которые работают в тысячи раз медленнее, если конкретная оптимизация сломана (например, кэш длины utf8 в длинных строках utf8). Добавьте тест, который обычно займет долю секунды, а в противном случае минуты, вызывая тайм-аут файла теста при сбое.

Сборка perl на старых коммитах

В процессе работы над основным дистрибутивом Perl вам может понадобиться настроить, собрать и протестировать perl на старом коммите. Иногда make будет завершаться сбоем во время этого процесса. Если это произойдет, вы сможете исправить ситуацию, используя библиотеку Devel::PatchPerl из CPAN (не включен в ядро), чтобы привести исходный код в этом коммите в состояние, пригодное для сборки.

Вот реальный пример, взятый из работы, выполненной для решения perl #72414. Использование Porting/bisect.pl выявило коммит ba77e4cc9d1ceebf472c9c5c18b2377ee47062e6 как коммит, в котором ошибка была исправлена. Для подтверждения разработчик P5P хотел настроить и собрать perl в коммите ba77e4c^ (предположительно "плохой"), а затем в ba77e4c (предположительно "хороший"). Была предпринята обычная конфигурация и сборка:

$ sh ./Configure -des -Dusedevel
$ make test_prep

make, однако, завершился сбоем с выводом (фрагмент) подобным этому:

cc -fstack-protector -L/usr/local/lib -o miniperl \
  gv.o toke.o perly.o pad.o regcomp.o dump.o util.o \
  mg.o reentr.o mro.o hv.o av.o run.o pp_hot.o sv.o \
  pp.o scope.o pp_ctl.o pp_sys.o doop.o doio.o regexec.o \
  utf8.o taint.o deb.o universal.o globals.o perlio.o \
  perlapi.o numeric.o mathoms.o locale.o pp_pack.o pp_sort.o  \
  miniperlmain.o opmini.o perlmini.o
pp.o: In function `Perl_pp_pow':
pp.c:(.text+0x2db9): undefined reference to `pow'
...
collect2: error: ld returned 1 exit status
makefile:348: recipe for target 'miniperl' failed
make: *** [miniperl] Error 1

Другой участник P5P рекомендовал установить и использовать Devel::PatchPerl в этой ситуации, сначала для определения версии perl в рассматриваемом коммите, а затем для исправления исходного кода в этом месте, чтобы облегчить сборку.

$ perl -MDevel::PatchPerl -e \
    'print Devel::PatchPerl->determine_version("/path/to/sourcecode"), "\n";'
5.11.1
$ perl -MDevel::PatchPerl -e \
    'Devel::PatchPerl->patch_source("5.11.1", "/path/to/sourcecode");'

После того, как исходный код был исправлен, ./Configure и make test_prep были вызваны и успешно завершены, что позволило подтвердить выводы в RT #72414.

ДОПОЛНИТЕЛЬНОЕ ЧТЕНИЕ ДЛЯ ХАКЕРОВ ВНУТРЕННОСТЕЙ

Чтобы взломать внутренности Perl, вам нужно будет прочитать следующее:

  • perlsource

    Обзор дерева исходных кодов Perl. Это поможет вам найти нужные файлы.

  • perlinterp

    Обзор исходного кода интерпретатора Perl и некоторые подробности о том, как Perl делает то, что он делает.

  • perlhacktut

    Этот документ описывает создание небольшого патча к C-коду Perl. Если вы только начинаете заниматься взломом ядра Perl, это поможет вам понять, как это работает.

  • perlhacktips

    Более подробная информация о взломе ядра Perl. Этот документ посвящен деталям более низкого уровня, таким как написание тестов, проблемы компиляции, переносимость, отладка и т. д.

    Если вы планируете серьезно заниматься взломом на C, обязательно прочитайте это.

  • perlguts

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

    «Иллюстрированный perlguts» Гисля Ааса, также известный как illguts, содержит очень полезные изображения:

    http://search.cpan.org/dist/illguts/

  • perlxstut и perlxs

    Рабочее знание программирования XSUB невероятно полезно для взлома ядра; XSUB используют методы, взятые из кода PP, той части внутренностей, которая фактически выполняет программу Perl. Гораздо проще изучить эти методы на простых примерах и объяснениях, чем на самом ядре.

  • perlapi

    Документация по API Perl объясняет, что делают некоторые внутренние функции, а также многие макросы, используемые в исходном коде.

  • Porting/pumpkin.pod

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

ТЕСТЕРЫ CPAN И КУРИЛЬЩИКИ PERL

Тестеры CPAN ( http://testers.cpan.org/ ) — это группа добровольцев, которые тестируют модули CPAN на различных платформах.

Perl Smokers ( http://www.nntp.perl.org/group/perl.daily-build/ и http://www.nntp.perl.org/group/perl.daily-build.reports/ ) автоматически тестируют релизы исходного кода Perl на платформах с различными конфигурациями.

Оба проекта приветствуют добровольцев. Чтобы участвовать в дымовом тестировании самого perl, посетите http://search.cpan.org/dist/Test-Smoke/. Чтобы начать дымовое тестирование модулей CPAN, посетите http://search.cpan.org/dist/CPANPLUS-YACSmoke/ или http://search.cpan.org/dist/minismokebox/ или http://search.cpan.org/dist/CPAN-Reporter/.

ЧТО ДАЛЬШЕ?

Если вы прочитали всю документацию в этом документе и те, что перечислены выше, вы более чем готовы взломать Perl.

Вот еще несколько рекомендаций

  • Подпишитесь на perl5-porters, следите за патчами и попытайтесь понять их; не стесняйтесь спрашивать, если есть часть, которая вам не ясна — кто знает, вы можете обнаружить ошибку в патче...

  • Обязательно прочитайте README, связанный с вашей операционной системой, например, README.aix в ОС IBM AIX. Не стесняйтесь предоставлять патчи к этому README, если вы обнаружите что-либо отсутствующее или измененное в новой версии ОС.

  • Найдите область Perl, которая кажется вам интересной, и посмотрите, сможете ли вы понять, как она работает. Просмотрите исходный код и пошагово пройдитесь по нему в отладчике. Играйте, ковыряйтесь, исследуйте, возитесь! Вы, вероятно, поймете не только выбранную вами область, но и гораздо более широкий спектр деятельности perl, и, вероятно, быстрее, чем вы думаете.

«Дорога тянется всё дальше и дальше, вниз от двери, где она началась.»

Если вы можете сделать это, вы начали долгий путь к портированию Perl. Спасибо за желание помочь сделать Perl лучше — и счастливого взлома!

Метафорические цитаты

Если вы узнали цитату о дороге выше, вам повезло.

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

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

Цитаты взяты из сочинений Дж. Р. Р. Толкина, относящихся к его Легендариуму, почти всегда из Властелина колец. Номера глав и страниц приводятся с использованием следующих изданий:

  • Хоббит, Дж. Р. Р. Толкин. Использовалось твердое издание к 70-летию 2007 года, опубликованное в Великобритании издательством Harper Collins Publishers и в США издательством Houghton Mifflin Company.

  • Властелин колец, Дж. Р. Р. Толкин. Использовалось твердое издание к 50-летию 2004 года, опубликованное в Великобритании издательством Harper Collins Publishers и в США издательством Houghton Mifflin Company.

  • Песни Белерианда, Дж. Р. Р. Толкин, опубликовано посмертно его сыном и литературным душеприказчиком К. Дж. Р. Толкином, будучи 3-м из 12 томов в огромной Истории Средиземья Кристофера. Номера страниц взяты из твердого переплета, впервые опубликованного в 1983 году издательством George Allen & Unwin; номера страниц не изменились для специального 3-томного сборного издания 2002 года или различных изданий в мягкой обложке, все снова теперь от Harper Collins или Houghton Mifflin.

Другие книги JRRT, подходящие для цитат, включают Приключения Тома Бомбадила, Сильмариллион, Неоконченные сказания и Повесть о детях Хурина, все, кроме первой, собраны посмертно CJRT. Но сам Властелин колец идеально подходит и, вероятно, лучше всего цитировать из него, при условии, что вы сможете найти там подходящую цитату.

Поэтому, если вы собираетесь предоставить новый, полный исходный файл верхнего уровня для добавления в Perl, вы должны сами следовать этой своеобразной практике, выбрав соответствующую цитату из Толкина, сохранив оригинальное написание и пунктуацию и используя тот же формат, что и остальные цитаты. Косвенное и непрямое — это прекрасно; помните, это метафора, поэтому быть мета — это, в конце концов, то, для чего она предназначена.

АВТОР

Этот документ был первоначально написан Натаном Торкингтоном и поддерживается списком рассылки perl5-porters.

© 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.28.3/perlhack

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API