Опубликован язык программирования Ruby 3.3

Состоялся релиз Ruby 3.3.0, динамического объектно-ориентированного языка программирования, отличающегося высокой эффективностью разработки программ и вобравшего в себя лучшие черты Perl, Java, Python, Smalltalk, Eiffel, Ada и Lisp. Код проекта распространяется под лицензиями BSD («2-clause BSDL») и «Ruby», которая ссылается на последний вариант лицензии GPL и полностью совместима с GPLv3.

Основные улучшения:

  • В основной состав включён парсер Prism, реализованный в форме Си-библиотеки libprism, задействованной в интерпретаторе CRuby, и gem-пакета на языке Ruby, предоставляющем общедоступный API для нисходящего рекурсивного разбора кода на языке Ruby, пригодный для использования в рабочих проектах вместо парсера Ripper. Из достоинств Prism отмечается хорошая переносимость и гибкая обработка ошибок в коде. Для включения нового парсера можно использовать опцию «ruby —parser=prism» или переменную окружения RUBYOPT=»—parser=prism». Для разбора кода в своих программах доступны методы Prism.parse(source) для получения AST-представления кода,
    Prism.parse_comments(source) для выделения комментариев из кода и Prism.parse_success?(source) для проверки наличия ошибок в коде.

  • Вместо внешнего пакета Bison для генерации парсеров задействован проект Lrama, предоставляющий реализацию алгоритма LALR на языке Ruby, поддерживающий Bison-совместимые определения грамматик (parse.y), используемые в CRuby, и реализующий расширенные возможности, такие как обработка ошибок и параметризированные правила (?, *, +).
  • Проведена значительная оптимизация производительности JIT-компилятора YJIT, развиваемого разработчиками платформы электронной коммерции Shopify в рамках инициативы по увеличению производительности Ruby-программ, использующих фреймворк Rails и вызывающих очень много методов. В отличие от ранее используемого JIT-компилятора MJIT новый YJIT применяет версионирование базовых блоков (LBBV — Lazy Basic Block Versioning) вместо обработки методов целиком и реализован в форме интегрированного JIT-компилятора, написанного на языке Rust. Благодаря LBBV, JIT вначале компилирует только начало метода, а оставшуюся часть компилирует через некоторое время, после того как в процессе выполнения будет определены типы используемых переменных и аргументов.

    При тестировании выполнения эмулятора Optcarrot производительность при использовании YJIT более чем в три раза превышает выполнение при помощи интерпретатора. В новой версии обеспечено выделение регистров для стековых операций виртуальной машины, расширен спектр компилируемых вызовов с необязательными аргументами, реализовано inline-развёртывание базовых и специализированных методов, добавлены отдельные оптимизации для операций «Integer#*», «Integer#!=», «String#!=», «String#getbyte», «Kernel#block_given?», «Kernel#is_a?», «Kernel#instance_of?» и «Module#===». Значительно увеличена скорость компиляции.

    Заметно снижено потребление памяти на хранение метаданных и обеспечена генерация более компактного кода для архитектуры ARM64. По умолчанию отключён сборщик мусора Code («—yjit-code-gc»), динамически высвобождающий неиспользуемый сгенерированный машинный код, но приводящий к проседанию производительности во время сборки мусора.
    Добавлен метод RubyVM::YJIT.enable для управления включением YJIT во время работы, без необходимости запуска с определённым параметром командной строки или переменной окружения. Расширена статистика, выдаваемая при указании опции «—yjit-stats». Добавлены режимы профилирования производительности (—yjit-perf) и трассировки (—yjit-trace-exits).

  • Предложен новый JIT-компилятор RJIT, написанный целиком на языке Ruby и заменяющий MJIT, но в отличие от последнего при использовании не требующий Си-компилятора. RJIT поддерживает только архитектуру x86-64 и Unix-подобные платформы.
  • Добавлен планировщик потоков «M:N», позволяющий для сокращения накладных расходов на создание и управление потоками использовать ограниченное число потоков операционной системы для обработки потоков в коде на языке Ruby. По умолчанию используется 8 потоков ОС (можно изменить через переменную окружения RUBY_MAX_CPU). Применение планировщика «M:N» может привести к проблемам с совместимостью с расширениями на языке Си, поэтому он отключён по умолчанию для основного (main) класса Ractor, но включён для неосновных (non-main). Для принудительного включения планировщика «M:N» следует выставить переменную окружения RUBY_MN_THREADS=1.
  • Расширены возможности оболочки интерактивных вычислений IRB(REPL, Read-Eval-Print-Loop). Добавлен режим отладки irb:rdbg, эквивалентный по своим возможностям отладчику pry-byebug. Добавлена поддержка многостраничного просмотра вывода команд ls, show_source и show_cmds. Реализована экспериментальная поддержка автоматического дополнения ввода, учитывающая типы данных. Предоставлены команды для изменения цвета и стиля шрифта.
  • Объявлен устаревшим вызов метода «it» без аргументов в блоке без параметров (например, «[1, 2, 3].each { puts it }»).
  • В RubyGems и Bundler включён вывод предупреждения в случае указания в «require» gem-пакетов
    abbrev,
    base64,
    bigdecimal,
    csv,
    drb,
    getoptlong,
    mutex_m,
    nkf,
    observer,
    racc,
    resolv-replace,
    rinda и
    syslog, если они не добавлены в Gemfile или gemspec. В будущих версиях Ruby данные gem-пакеты будут встроены в основной состав.

  • Обновлены версии встроенных и входящих в стандартную библиотеку gem-модулей.

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