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

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

Ветка 5.26 выпущена в соответствии с утверждённым пять лет назад фиксированным графиком разработки, подразумевающим выпуск новых стабильных веток раз в год и корректирующих релизов — раз в три месяца. Примерно через месяц планируется выпустить первый корректирующий релиз Perl 5.26.1, в котором будут исправлены наиболее значительные ошибки, выявленные в процессе внедрения Perl 5.24.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 лет.

© OpenNet