После года разработки состоялся релиз новой стабильной ветки языка программирования 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 лет.


Источник: http://www.opennet.ru/opennews/art.shtml?num=46628