Релиз языка программирования Perl 5.26.0

После года разработки состоялся релиз новой стабильной ветки языка программирования Perl — 5.26. При подготовке нового выпуска было изменено около 360 тыс. строк кода, изменения затронули 2600 файлов, в разработке приняли участие 86 разработчиков.

Ветка 5.26 выпущена в соответствии с утверждённым пять лет назад фиксированным графиком разработки, подразумевающим выпуск новых стабильных веток раз в год и корректирующих релизов — раз в три месяца. Примерно через месяц планируется выпустить первый корректирующий релиз Perl 5.26.1, в котором будут исправлены наиболее значительные ошибки, выявленные в процессе внедрения Perl 5.26.0. Одновременно с выходом Perl 5.26 прекращена поддержка ветки 5.22, для которой в будущем могут быть выпущены обновления только в случае выявления критических проблем с безопасностью. Также начался процесс разработки экспериментальной ветки 5.27, на базе которой в апреле или мае 2018 года будет сформирован стабильный релиз Perl 5.28.

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

  • Из соображении безопасности текущая директория «.» по умолчанию больше не дополняется в виде последнего элемента в @INC. Такое поведение в отношении @INC теперь аналогично тому как если бы ранее был активирован режим «Taint» (ключ запуска «-T»). Данная схема может создать проблемы при сборке, тестировании, установке модулей и исполнении скриптов. Существует несколько простых способов вернуть прежнее поведение perl:
    • Схема отключения реализована через включение по умолчанию опции «-Udefault_inc_excludes_dot» для Configure. Поэтому если можно аннулировать значение «-Udefault_inc_excludes_dot» для Configure и пересобрать perl;
    • Perl проверяет переменную окружения PERL_USE_UNSAFE_INC в момент запуска и если переменная определена, то в @INC будет добавлен «.» как прежде (как пример: alias perl=»env PERL_USE_UNSAFE_INC=1 perl»);
    • Если допустимо добавление «.» первым элементом в @INC, то можно использовать схему perl -I. (например alias perl=»perl -I.» в рабочей сессии окружения)
  • Оператор «do» теперь выдает предупреждения на попытку загрузки файла который не нашелся в @INC без «.», но обнаружился в текущей директории. Файл может быть загружен путем явного указания пути: ‘do «./file.pl»‘. Выполнение с «-I.» и использование PERL_USE_UNSAFE_INC не приводит к предупреждениям при использовании do.
  • В регулярных выражениях открывающая фигурная скобка «{» должна быть экранирована или заключена в определитель класса «[{]». Данное нововведение дает возможность для реализации новых конструкции в регулярных выражениях в будущем. В perldiag в секции «Unescaped left brace in regex is deprecated here» можно найти детали, например, о случаях когда «{» может не экранироваться.

Ключевые изменения:

  • С процедур лексической области видимости введенных в 5.18 снят статус экспериментальной возможности.
    Попытка определить лексическую процедуру больше не приведет к ошибкам и предупреждению. Изменения введены таким образом, что сохранена обратная совместимость с ранее использованными схемами через использование «experimental::lexical_subs» и «lexical_subs» из «feature». Включение «lexical_subs» через «feature» не прервет выполнение программы, так как сохранилось в виде бездействующей заглушки и лексические процедуры теперь доступны всегда в областях видимости без их явного включения;

  • Введена поддержка выравнивания встроенных документов (here-documents). Новый модификатор «~», добавленный в синтаксис объявления here-документов, дает понять синтаксическому анализатору, что в коде встроенный документ будет выровнен на величину пробельного символа (символы из группы whitespace). Это позволяет определить в программе следующую конструкцию которая выглядит без нарушения вложенности:
       if (1) {
         print {{~EOF;
           Hello there
           EOF
       }
    

    Обратите внимание на то, что лексический анализатор в процессе поиска лексем будет, во-первых, проверять выравнивание строк, и, во-вторых, удалять с начала строки here-документа такую же подстроку которая предшествует закрывающему элементу here-документа. То есть если в нашем примере перед EOF стоит «t», то перед ‘Hello there’ будет попытка удалить «t». Анализатор сообщит об ошибке выравнивания here-документов если перед «Hello there» не будет «t». Если будет два или более «t» перед «Hello there», то удалится только один;

  • Новый модификатор регулярного выражения «/xx» который является своего рода «усиленной формой /x». Работает также как и «/x» с той лишь разницей, что с модификатором «/xx» в регулярном выражении игнорируются неэкранированные символы пробела и табуляции в определителе класса символов «[]».

    Пример: выражение » q»=~/^[^1 2]q/x не даст результат того, что кроме 1 и 2 определен пробел в [^1 2]

    а выражение » q»=~/^[^1 2]q/xx даст результат, так как пробел в [^1 2] игнорируется и снова выражение » q»!~/^[^1 2]q/xx дает результат;

  • Новые переменные «@{^CAPTURE}», «%{^CAPTURE}» и «%{^CAPTURE_ALL}» для захвата результата работы регулярного выражения:
    • «@{^CAPTURE}» — массив включающий в себя $1, $2 и т.д. по порядку; пример: «asdf»=~/a(s)d(f)/o даст ‘s’ и ‘f’ в массив;
    • «%{^CAPTURE}» — эквивалент «%+», использующийся для именованного захвата;
    • «%{^CAPTURE_ALL}» эквивалент для «%-«, использующийся для всех именованных захватов (от автора: мне не удалось установить соответствие «%{^CAPTURE_ALL}» и «%-«, похоже, что «%{^CAPTURE}» и «%{^CAPTURE_ALL}» синонимы; не исключено, что это ошибка, требуется перепроверка).
  • Новая экспериментальная конструкция: объявление ссылок на переменную. В Perl 5.22.0 была введена экспериментальная конструкция присваивания к ссылке («use feature ‘refaliasing'»), которая позволяет определить псевдоним. Как логическое продолжение данной идеи теперь реализована возможность объявления ссылки на переменную в виде «my $x» (эквивалент «my $x»). Данная возможность включается через «use feature ‘declared_refs'» и позволяет использовать схему «my ($foo, @bar, %baz)» — эквивалентен записи my $foo, my(@bar, %baz). Обе схемы работают с my(), state(), our() и local();
  • Поддержана спецификация Unicode 9.0. Поддержка модулями из core Perl реализована через приведение нормализатора форм Unicode::Normalize к соответствию стандарту Unicode 9.0;
  • На платформах которые поддерживают UTF-8 по умолчанию для сопоставления данных теперь используется кодировка UTF-8.
    Для портируемости рекомендуется использовать Unicode::Collate. Подробности в разделе «Category LC_COLLATE: Collation: Text Comparisons and Sorting» в perllocale;

  • Возможность косвенного вызова функции интерпретатора perl для массивов и хэшей. Функции обработки массивов и хешей (keys, each, values, push, pop, shift, unshift и splice) пространства имен CORE могут быть вызваны как через форму с префиксом «» (CORE::keys(%hash)), так и косвенным вызовом (my $k = CORE::keys; $k-(%hash)). До 5.26.0 эти формы приводили к ошибке выполнения;
  • Новый алгоритм хэширования для 64-битных сборок. Для лучшей производительности реализована схема гибридного хэширования: для коротких ключей до 16 бит включительно используется оптимизированный вариант алгоритма «One At A Time Hard», для длинных ключей используется «Siphash 1-3». Данная схема показала значительный прирост в производительности для очень длинных ключей и умеренный прирост для остальных случаев.

Изменения, нарушающие совместимость:

  • Конструкция scalar(%hash) теперь возвращает количество использованных ключей аналогично 0+keys(%hash). Информация об использованных и выделенных блоках теперь доступна через Hash::Util::bucket_ratio() (функция работает аналогично конструкции scalar(%hash) до версии 5.26);
  • Запрещено изменение значения возвращаемого функцией keys из lvalue-программы в контексте списка (bug #128187);
  • Удалена объявленная ранее устаревшей переменная «${^ENCODING}» и прекращена поддержка режима «use encoding [‘ENCNAME’]» в пользу использования UTF-8 по умолчанию. В случаях когда требуется использовать исходный код который представлен в кодировке отличной от UTF-8 рекомендуется использовать source-фильтры как Filter::Encoding из CPAN, либо использовать опцию Filter модуля encoding;
  • Удалена реализация небезопасной функции POSIX::tmpnam(), объявленной устаревшей в версии 5.22. Теперь она выдает ошибку с рекомендацией по использованию модуля File::Temp;
  • Запрещено использование модулей, начинающихся с двух двоеточии. Схема «require ::Foo::Bar» ранее приводила к попытке чтения модуля /Foo/Bar.pm. Схема загрузки по require «/Foo/Bar.pm» осталась без изменении;
  • Запрещено использование управляющих литералов в именах переменных в исходном коде (bug #119123), так как это приводит к непоправимым ошибкам в исходном коде и создает код, непереносимый на другие платформы.
  • В именах символов «N{…}» больше не разрешается использовать неразрывный (NBSP) пробел. Такое использование было объявлено устаревшим в версии 5.22;

Оптимизации производительности:

  • Выражение с хэшем в булевом контексте иногда может вычислиться быстрее «if (!%h) {…}»;
  • Гибридная хэш-функция для 64-битных сборок (детали описаны выше по тексту);
  • Функции для чтения файла по строкам «readline()» и «{» улучшена за счет ускорения кода поиска вхождения следующего символа новой строки;
  • Присваивание ссылок «$ref1 = $ref2» оптимизировано для некоторых случаев;
  • Удалены некоторые исключения для создания COW-строк, поскольку алгоритм наращивания буфера был значительно переработан, что существенно снизило вероятность невозможности создания COW-строк при котором происходит вынужденное копирование;
  • Оптимизация присваивания массивов и хешей; пример кода который оказался втрое быстрее, чем реализация в версии 5.24:
        my @a;
        for my $i (1..10_000_000) {
          @a = (1,2,3);
          @a = ();
        }
    
  • Значительно ускорена конвертация односимвольной строки состоящей из цифры в число;
  • Функция split теперь быстрее в следующих случаях:
        my    @a = split ...;
        local @a = split ...;
    

Важные изменения в CORE-модулях:

  • attributes = 0.29; атрибуты «:unique» и «:locked» будут удалены в выпуске Perl 5.28.
  • Data::Dumper = 2.167; в XS-реализации появилась поддержка Deparse.
  • Errno = 1.248; указано, что использование «%!» приводит к автоматической загрузке модуля Errno.
  • File::Glob = 1.28; выдает предупреждение о том, что использование File::Glob::glob() является устаревшим.
  • HTTP::Tiny = 0.070; каскад ошибок с кодом 599 теперь включает историю редиректов.
  • Net::Ping = 2.55; реализована поддержка IPv6-адресов и AF_INET6-сокетов.
  • POSIX = 1.76; интерфейс POSIX::tmpnam() удален. Кроме этого удалены ряд функции: POSIX::isalnum, POSIX::isalpha, POSIX::iscntrl, POSIX::isdigit, POSIX::isgraph, POSIX::islower, POSIX::isprint, POSIX::ispunct, POSIX::isspace, POSIX::isupper, POSIX::isxdigit, POSIX::tolower, POSIX::toupper. Попытка импорта этих функции выдаст ошибку компиляции а не исполнения.
  • re = 0.34; добавлена поддержка модификатора «/xx» (описано выше); режим strict модуля ‘re’ объявлен экспериментальным.
  • Thread::Semaphore = 2.13; добавлен метод down_timed (попытка выполнить операцию декремента на счетчике семафора за определенное время).
  • Time::HiRes = 1.9741; теперь собирается на системах с компиляторами, соответствующим стандарту C++11 (G++ 6 and Clang++ 3.9). Задействовано использование clockid_t.
  • XSLoader = 0.27; обновление безопасности, закрывающее уязвимость, которая позволяла загрузить двоичные образы за пределами @INC.

Прочие изменения:

  • Новый раздел документации perldeprecation, который содержит всю информацию о конструкциях, объявленных устаревшими.
  • Утилиты c2ph и pstruct удалены из дистрибутива, так как давно были замененными утилитой h2xs.
  • Perl может быть скомпилирован и запущен в порте NetBSD для платформы VAX, но с некоторыми ограничениями из-за особенностей платформы. Сборка показывает 98% успешных тестов.
  • Реализована возможность сборки Perl компилятором Visual C++ 14.0 из состава пакета Microsoft Visual Studio 2015.
  • На платформе Linux перестал поддерживаться устаревший формат a.out, так как формат elf используется в Linux уже более 20 лет.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.