Состоялся релиз Ruby 3.4.0, динамического объектно-ориентированного языка программирования, сосредоточенного на высокой эффективности разработки программ и вобравшего в себя лучшие черты Perl, Java, Python, Smalltalk, Eiffel, Ada и Lisp. Код проекта распространяется под лицензиями BSD ("2-clause BSDL") и "Ruby", которая ссылается на последний вариант лицензии GPL и совместима с GPLv3.
Основные улучшения:
Добавлен новый идентификатор "it", отождествлённый с неименованным параметром, выставляемым в блоке по умолчанию. Новый идентификатор аналогичен ранее доступной переменной "_1" при передаче в блок одного параметра. Введение нового идентификатора объясняется желанием избавиться от путаницы, вызванной возможностью передачи в блок нескольких параметров ("it" подразумевает, что всегда имеется только один аргумент, а при указании "_1", не ясно, существует ли параметр "_2").
[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.parse(source) для получения AST-представления кода, Prism.parse_comments(source) для выделения комментариев из кода и Prism.parse_success?(source) для проверки наличия ошибок в коде. Для возвращения ранее применявшегося парсера "parse.y" можно использовать опцию "--parser=parse.y".
В библиотеке "socket" реализована и включена по умолчанию поддержка алгоритма Happy Eyeballs (RFC 8305) для выбора оптимального протокола при подключении к хостам, одновременно доступным по адресам IPv4 и IPv6. При использовании алгоритма Happy Eyeball клиент сразу резолвит адреса IPv4 и IPv6 для хоста и отправляет запрос на соединение по IPv6, а затем с задержкой 250 мс пытается параллельно подключиться по другим привязанным к хосту адресам, не дожидаясь результата предпринятых ранее попыток подключения. Активным оставляется соединение, которое было установлено первым, а остальные закрываются. До этого, вызов методов TCPSocket.new и Socket.tcp в программах на языке Ruby приводил к последовательным попыткам резолвинга адресов IPv4/IPv6 и подключения, что приводило к задержкам, например, когда первой была попытка подключения по IPv6, но система не поддерживала IPv6. Для возвращения старого поведения можно использовать переменную окружения "RUBY_TCP_NO_FAST_FALLBACK=1", настройку "Socket.tcp_fast_fallback=false" или аргумент "fast_fallback: false" при вызове методов.
Продолжена оптимизация производительности JIT-компилятора YJIT, развиваемого разработчиками платформы электронной коммерции Shopify в рамках инициативы по увеличению производительности Ruby-программ, использующих фреймворк Rails и вызывающих очень много методов. В отличие от JIT-компилятора MJIT новый YJIT применяет версионирование базовых блоков (LBBV - Lazy Basic Block Versioning) вместо обработки методов целиком и реализован в форме интегрированного JIT-компилятора, написанного на языке Rust. Благодаря LBBV, JIT вначале компилирует только начало метода, а оставшуюся часть компилирует через некоторое время, после того как в процессе выполнения будет определены типы используемых переменных и аргументов.
В новой версии в большинстве тестов на системах x86_64 и ARM64 удалось добиться повышения производительности YJIT. Добавлены новые оптимизации: использование регистров для локальных переменных и аргументов методов; задействование Ruby-реализаций Array#each, Array#select и Array#map; inline-развёртывание пустых методов и методов, возвращающих константы, собственный экземпляр или входной аргумент; отдельные генераторы кода для определённых методов; оптимизация работы со строками (String#getbyte, String#setbyte); ускорение битовых операций.
Сокращено потребление памяти за счёт сжатия метаданных и реализации унифицированной системы ограничений. Добавлена опция "--yjit-mem-size", по умолчанию выставленная в значение 128MiB и влияющая на общее потребление памяти. Добавлена опция "--yjit-log" для включения отслеживания, какой именно код компилируется.
Предоставлена возможность динамической загрузки альтернативных сборщиков мусора, собранных в форме разделяемых библиотек. Для указания библиотеки с необходимым сборщиком мусора следует использовать переменную окружения RUBY_GC_LIBRARY. Задействованный по умолчанию встроенный сборщик мусора теперь может быть собран в форме отдельной библиотеки. В качестве альтернативы добавлен сборщик мусора на базе фреймворка MMTk, написанного на языке Rust.
Разрешена передача в методы именованных аргументов, имеющих значение nil. Аргументы со значением "**nil" теперь обрабатываются как пустой хэш "**{}" без передачи именованных аргументов в метод.
В индексах запрещена передача блоков и указание именованных аргументов, например, "a[&b]=c" и "o[1, a: 1]".
Оптимизирован метод JSON.parse, который теперь работает в полтора раза быстрее пакета json 2.7.
Источник: https://www.opennet.ru/opennews/art.shtml?num=62467