Spec-Zone.ru › Perl 5.36

perlhack

СОДЕРЖАНИЕ

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

NAME

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

DESCRIPTION

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

КРАТКОЕ РУКОВОДСТВО ПО ПРАВКАМ

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

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

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

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

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

    % perldoc pod/perlhack.pod
  • Создайте ветку для вашего изменения

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

    % git checkout -b mychange
  • Внесите изменения

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

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

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

    % ./Configure -des -Dusedevel
    % make test

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

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

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

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

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

  • Отправьте изменения в систему отслеживания проблем Perl

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

    Создайте GitHub-форк репозитория perl5 и добавьте его как удаленный, если вы еще не сделали этого, как описано в документации GitHub по адресу https://help.github.com/en/articles/working-with-forks.

    % git remote add fork git@github.com:MyUser/perl5.git

    Для получения дополнительной информации см. "Подключение к GitHub с помощью SSH".

    Если вы предпочитаете использовать URL HTTPS для вашего git push см. "Клонирование с использованием URL HTTPS".

    % git remote add fork https://github.com/MyUser/perl5.git

    Затем отправьте свою новую ветку в свой форк.

    % git push -u fork mychange

    Наконец, создайте запрос на вытягивание на GitHub из вашей ветки в blead, как описано в документации GitHub по адресу https://help.github.com/en/articles/creating-a-pull-request-from-a-fork.

  • Спасибо

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

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

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

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

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

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

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

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

Если вы хотите сообщить об ошибке в Perl или просмотреть существующие ошибки и патчи Perl, используйте систему отслеживания проблем GitHub по адресу https://github.com/perl/perl5/issues.

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

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

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

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

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

Рассылка perl-changes

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

#p5p на IRC

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

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

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

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

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

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

% git clone git@github.com:Perl/perl5.git perl

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

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

% git clone https://github.com/Perl/perl5.git perl

Доступ для чтения через веб

Вы можете получить доступ к репозиторию через веб. Это позволяет вам просматривать дерево, видеть последние коммиты, подписываться на уведомления репозитория, искать определенные коммиты и многое другое. Вы можете получить к нему доступ по адресу https://github.com/Perl/perl5.

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

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

ПАТЧИНГ PERL

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

Отправка патчей

Если у вас есть небольшой патч для отправки, отправьте его через рабочий процесс GitHub Pull Request. Вы также можете отправлять патчи в список p5p.

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

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

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

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

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

Стиль патча

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

Если вы использовали 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 столбцов

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

  • Прототипы 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. Когда автор обновляет модуль, обновления просто копируются в ядро. См. документацию этого модуля или его список на https://metacpan.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 — Есть больше одного способа сделать это, я колеблюсь сделать 10 способов сделать что-то». Однако это сложная эвристика для навигации — то, что один человек считает существенным дополнением, другой считает бессмысленным мусором.

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

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

Патчи говорят громче слов

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

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

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

Есть три способа написать тест в ядре: Test::More, t/test.pl и специализированные 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, или даже подпрограммы, используйте для этих трех специализированные тесты. Действуйте осторожно, чтобы избежать использования тестируемой функции. Тесты в t/opbasic, например, были помещены туда, а не в t/op, потому что они проверяют функциональность, которую t/test.pl предполагает, что уже была продемонстрирована как работающая.

  • Все остальные подкаталоги t/

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

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

  • Тестовые файлы, не найденные в t/

    Эта категория включает файлы .t в подкаталогах, таких как dist, ext и lib. Поскольку ядро Perl теперь протестировано, Test::More может и теперь должен использоваться. Вы также можете использовать полный набор основных модулей в тестах. (Как отмечено в разделе "Патчинг основного модуля" выше, изменения в файлах .t, найденных в cpan/, должны быть отправлены основным разработчикам этих модулей.)

Когда вы говорите "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' на всех платформах. Побочные эффекты:

  • Они выбирают правила Unicode. Это означает, что в строках в двойных кавычках строка всегда преобразуется в UTF-8, чтобы принудительно применить интерпретацию Unicode (вы можете 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.

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

  • 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-подобных и Windows платформах. В Unix, вместо запуска make test, установите TEST_JOBS в вашей среде на число тестов для параллельного запуска и запустите make test_harness. В оболочке типа Bourne это можно сделать так:

TEST_JOBS=3 make test_harness  # Run 3 tests in parallel

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

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

TEST_JOBS=19 PERL_TEST_HARNESS_ASAP=1 make -j19 test_harness

вы даёте сигнал, что хотите, чтобы тесты завершились за максимально короткое реальное время. После завершения тестов работоспособности это приводит к тому, что остальные упаковываются в доступные ядра так плотно, как мы знаем как. Это наиболее эффективно на медленных многоядерных системах. Производительность была увеличена на 20% на устаревшей 24-ядерной системе; меньше на более новых быстрых системах с меньшим числом ядер.

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

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

Вы можете запустить часть набора тестов вручную, используя одну из следующих команд из каталога 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

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

  • PERL_CORE=1

    указывает, что мы запускаем этот тест как часть тестового набора ядра perl. Это полезно для модулей, которые имеют двойную жизнь на 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 #10118. Использование 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 \
  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, содержит очень полезные иллюстрации:

    https://metacpan.org/release/RURBAN/illguts-0.49

  • perlxstut и perlxs

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

  • perlapi

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

  • Porting/pumpkin.pod

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

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

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

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

Оба проекта приветствуют добровольцев. Чтобы принять участие в дымовом тестировании самого perl, посетите https://metacpan.org/release/Test-Smoke. Чтобы начать дымовое тестирование модулей CPAN, посетите https://metacpan.org/release/CPANPLUS-YACSmoke или https://metacpan.org/release/minismokebox или https://metacpan.org/release/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.

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

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

АВТОР

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

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

Spec-Zone.ru

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