Привет, Хабр! На связи команда Selectel. Разработчики Ruby молодцы: прошло всего два месяца — и уже готов новый выпуск языка, на этот раз 3.4.0. Напомню, что это динамически объектно-ориентированный язык программирования. Его хвалят за возможность быстро разработывать приложения.
Ruby вобрал в себя лучшие черты таких языков, как Perl, Java, Python, Smalltalk, Eiffel, Ada и Lisp, чтобы предложить разработчикам простой и гибкий инструмент для решения задач. Код Ruby распространяется под лицензиями BSD («2-clause BSDL») и «Ruby», которая совместима с GPLv3 и ссылается на последнюю версию лицензии GPL. Но хватит о языке, давайте, наконец, поговорим о его новом выпуске.
Основные нововведения и улучшения
Новый идентификатор it. В язык добавили идентификатор
it
, который используется в качестве неименованного параметра по умолчанию в блоках. Он выполняет ту же функцию, что и ранее доступная переменная _1
, но упрощает понимание кода. Если _1
может вызвать путаницу, когда в блоке несколько аргументов (например, _2
или _3
), то it
всегда однозначно указывает на единственный параметр. Примеры использования:
[1, 2, 3].each { puts _1 }
[1, 2, 3].each { puts it }
ary = ["foo", "bar", "baz"]
p ary.map { it.upcase } #=> ["FOO", "BAR", "BAZ"]
Новый парсер Prism. В новой версии Ruby по умолчанию используется парсер Prism, который более переносим, удобен в сопровождении и позволяет эффективнее обрабатывать ошибки в коде. Также парсер предоставляет несколько новых методов:
- Prism.parse(source) — преобразует исходный код в AST-представление.
- Prism.parse_comments(source) — извлекает комментарии из кода.
- Prism.parse_success?(source) — проверяет наличие ошибок в коде.
Для тех, кто предпочитает старый парсер, предусмотрена возможность возврата к нему с использованием параметра
--parser=parse.y
.Поддержка Happy Eyeballs. В библиотеке socket появилась поддержка алгоритма Happy Eyeballs (RFC 8305), включенная по умолчанию. Алгоритм оптимизирует подключение к хостам, доступным одновременно через IPv4 и IPv6. Он параллельно отправляет запросы по обоим протоколам и выбирает соединение, установленное быстрее. До этого Ruby последовательно обрабатывал попытки подключения, что могло вызывать задержки, например, если IPv6 был доступен, но не поддерживался системой.
Для возврата к старому поведению можно использовать следующие параметры:
- Переменная окружения:
RUBY_TCP_NO_FAST_FALLBACK=1
. - Настройка:
Socket.tcp_fast_fallback=false
. - Аргумент метода:
fast_fallback: false
.
Улучшения в JIT-компиляторе YJIT. Компилятор YJIT, разработанный Shopify, получил множество оптимизаций для повышения производительности Ruby-программ. YJIT реализован на языке Rust и использует версионирование базовых блоков (LBBV), что позволяет компилировать только начало метода, а остальные части — по мере необходимости. Такой подход повышает эффективность работы, так как оптимизации выполняются на основе типов переменных и аргументов, определяемых в процессе выполнения.
В новой версии производительность YJIT улучшена на системах x86_64 и ARM64. Добавлены следующие оптимизации:
- Использование регистров для локальных переменных и аргументов.
- Оптимизация методов:
Array#each
,Array#select
,Array#map
. - Inline-развертывание пустых методов и методов, возвращающих константы, текущий объект или входные аргументы.
- Отдельные генераторы кода для некоторых методов.
- Ускорение операций со строками, включая
String#getbyte
иString#setbyte
. - Увеличение скорости битовых операций.
Для уменьшения потребления памяти внедрена унифицированная система ограничений и сжатие метаданных. Новая опция
--yjit-mem-size
задает общий объем памяти для JIT (по умолчанию 128 MiB). Также появилась опция --yjit-log
, которая позволяет отслеживать компилируемый код.Поддержка альтернативных сборщиков мусора. Теперь можно динамически загружать сторонние сборщики мусора, оформленные как разделяемые библиотеки. Для выбора сборщика следует указать библиотеку через переменную окружения RUBY_GC_LIBRARY. Встроенный сборщик также может быть собран в виде отдельной библиотеки. В новой версии добавлена поддержка MMTk — фреймворка, написанного на языке Rust.
Расширенная работа с аргументами. Теперь можно передавать в методы именованные аргументы со значением
nil
. Такие аргументы будут обрабатываться как пустой хэш (**{}).Запрещена передача блоков и именованных аргументов в индексах, например, выражения вида
a[&b]=c
и o[1, a: 1]
больше не поддерживаются.Ускорение JSON.parse. Метод
JSON.parse
в новой версии стал работать в 1,5 раза быстрее по сравнению с пакетом JSON версии 2.7.Скачать новую версию можно здесь.
Ruby 3.4.0 — значительный шаг вперед в развитии языка. Новая версия предлагает разработчикам улучшенную производительность, расширенные возможности для написания кода и улучшения, направленные на удобство использования.
alexeyrom
Это (
f(x: nil)
) можно было сделать с момента появления именованных аргументов. Теперь можно сделать**nil
внутри списка аргументов (естественно, в реальных случаях будет**expr
, где значениеexpr
равноnil
).