Релиз языка программирования 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