Вийшов Ruby 3.4.0

Опублікував naruse 25-12-2024
Переклав: Andrii Furmanets

Раді повідомити про вихід Ruby 3.4.0. Ruby 3.4 додає посилання на параметр блоку it, змінює Prism на парсер за замовчуванням, додає підтримку Happy Eyeballs Version 2 до бібліотеки сокетів, покращує YJIT, додає модульний GC тощо.

Введено it

it додано для посилання на параметр блоку без імені змінної. [Feature #18980]

ary = ["foo", "bar", "baz"]

p ary.map { it.upcase } #=> ["FOO", "BAR", "BAZ"]

it поводиться майже так само, як _1. Коли намір - використати в блоці лише _1, можливість появи інших нумерованих параметрів, таких як _2, створює додаткове когнітивне навантаження для читачів. Тому it введено як зручний псевдонім. Використовуйте it у простих випадках, де it говорить саме за себе, наприклад в однорядкових блоках.

Prism тепер парсер за замовчуванням

Перемкнуто парсер за замовчуванням з parse.y на Prism. [Feature #20564]

Це внутрішнє поліпшення, і для користувача має бути мало помітних змін. Якщо ви помітите проблеми сумісності, будь ласка, повідомте нам.

Щоб використати традиційний парсер, передайте параметр командного рядка --parser=parse.y.

Бібліотека сокетів тепер підтримує Happy Eyeballs Version 2 (RFC 8305)

Бібліотека сокетів тепер підтримує Happy Eyeballs Version 2 (RFC 8305), останню стандартизовану версію широко застосовуваного підходу для кращої мережевої взаємодії у багатьох мовах програмування, у TCPSocket.new (TCPSocket.open) та Socket.tcp. Це покращення дозволяє Ruby забезпечувати ефективні та надійні мережеві з’єднання, адаптовані до сучасних інтернет-умов.

До Ruby 3.3 ці методи виконували розв’язання імен і спроби з’єднання послідовно. За цим алгоритмом тепер вони працюють так:

  1. Виконують розв’язання імен IPv6 і IPv4 паралельно
  2. Підключаються до розв’язаних IP-адрес, віддаючи пріоритет IPv6, із паралельними спробами з інтервалом 250 мс
  3. Повертають перше успішне з’єднання, скасовуючи всі інші

Це мінімізує затримки підключення, навіть якщо певний протокол або IP-адреса затримується чи недоступні. Цю функцію увімкнено за замовчуванням, тож додаткових налаштувань не потрібно. Щоб вимкнути її глобально, встановіть змінну середовища RUBY_TCP_NO_FAST_FALLBACK=1 або викличте Socket.tcp_fast_fallback=false. А щоб вимкнути її для окремого виклику, використайте ключовий аргумент fast_fallback: false.

YJIT

TL;DR

  • Краща продуктивність у більшості бенчмарків на платформах x86-64 та arm64.
  • Зменшене використання пам’яті завдяки стисненим метаданим та єдиній межі пам’яті.
  • Різні виправлення помилок: YJIT став надійнішим і ретельніше протестованим.

Нові можливості

  • Параметри командного рядка
    • --yjit-mem-size запроваджує єдину межу пам’яті (типово 128MiB) для відстеження загального споживання пам’яті YJIT, забезпечуючи інтуїтивнішу альтернативу старому параметру --yjit-exec-mem-size.
    • --yjit-log увімкнює журнал компіляції, щоб відстежувати, що компілюється.
  • API Ruby
    • RubyVM::YJIT.log надає доступ до хвоста журналу компіляції під час виконання.
  • Статистика YJIT
    • RubyVM::YJIT.runtime_stats тепер завжди надає додаткову статистику щодо інвалідизації, інлайнінгу та кодування метаданих.

Нові оптимізації

  • Стиснений контекст зменшує пам’ять, потрібну для зберігання метаданих YJIT
  • Виділення регістрів для локальних змінних і аргументів методів Ruby
  • Коли YJIT увімкнено, більше базових примітивів реалізовано на Ruby:
    • Array#each, Array#select, Array#map переписано на Ruby для кращої продуктивності [Feature #20182].
  • Можливість інлайнити невеликі або тривіальні методи, такі як:
    • Порожні методи
    • Методи, що повертають константу
    • Методи, що повертають self
    • Методи, що безпосередньо повертають аргумент
  • Спеціалізована генерація коду для значно більшої кількості методів часу виконання
  • Оптимізація String#getbyte, String#setbyte та інших рядкових методів
  • Оптимізація бітових операцій для прискорення низькорівневих маніпуляцій з бітами/байтами
  • Підтримка розділюваних констант у режимі multi-ractor
  • Різні інші інкрементальні оптимізації

Модульний GC

  • Альтернативні реалізації збирача сміття (GC) можуть завантажуватися динамічно через функцію модульного GC. Щоб увімкнути цю функцію, сконфігуруйте Ruby з --with-modular-gc під час збірки. Бібліотеки GC можна завантажувати під час виконання, використовуючи змінну середовища RUBY_GC_LIBRARY. [Feature #20351]

  • Вбудований збирач сміття Ruby винесено в окремий файл gc/default/default.c і він взаємодіє з Ruby через API, визначений у gc/gc_impl.h. Вбудований збирач сміття тепер також можна зібрати як бібліотеку, використовуючи make modular-gc MODULAR_GC=default, і увімкнути через змінну середовища RUBY_GC_LIBRARY=default. [Feature #20470]

  • Експериментальна бібліотека GC на основі MMTk. Цю бібліотеку GC можна зібрати командою make modular-gc MODULAR_GC=mmtk і увімкнути через змінну середовища RUBY_GC_LIBRARY=mmtk. Для цього потрібен інструментарій Rust на машині збірки. [Feature #20860]

Зміни мови

  • Рядкові літерали у файлах без коментаря frozen_string_literal тепер видають попередження про застаріле використання при їх зміні. Ці попередження можна увімкнути за допомогою -W:deprecated або встановивши Warning[:deprecated] = true. Щоб вимкнути цю зміну, можна запустити Ruby з параметром командного рядка --disable-frozen-string-literal. [Feature #20205]

  • Тепер підтримується розпаковування ключових аргументів з nil під час виклику методів. **nil обробляється подібно до **{}, не передаючи ключових аргументів і не викликаючи жодних методів перетворення. [Bug #20064]

  • Передавання блоку більше не дозволено в операції індексації. [Bug #19918]

  • Ключові аргументи більше не дозволені в операції індексації. [Bug #20218]

  • Глобальне ім’я ::Ruby тепер зарезервоване, і при його визначенні буде попередження, якщо увімкнено Warning[:deprecated]. [Feature #20884]

Оновлення основних класів

Примітка: наведено лише помітні оновлення основних класів.

  • Exception

    • Exception#set_backtrace тепер приймає масив Thread::Backtrace::Location. Kernel#raise, Thread#raise та Fiber#raise також приймають цей новий формат. [Feature #13557]
  • GC

    • Додано GC.config, щоб дозволити встановлювати конфігураційні змінні збирача сміття. [Feature #20443]

    • Запроваджено параметр конфігурації GC rgengc_allow_full_mark. Коли false, GC позначає лише молоді об’єкти. Типово true. [Feature #20443]

  • Ractor

    • require у Ractor дозволено. Процес require буде виконано в основному Ractor. Додано Ractor._require(feature) для виконання процесу require в основному Ractor. [Feature #20627]

    • Додано Ractor.main?. [Feature #20627]

    • Додано Ractor.[] і Ractor.[]=, щоб отримувати доступ до локального сховища ractor поточного Ractor. [Feature #20715]

    • Додано Ractor.store_if_absent(key){ init } для ініціалізації локальних змінних ractor у thread-safety. [Feature #20875]

  • Range

    • Range#size тепер викликає TypeError, якщо діапазон не є ітерованим. [Misc #18984]

Оновлення стандартної бібліотеки

Примітка: наведено лише помітні оновлення стандартних бібліотек.

  • RubyGems
    • Додано параметр --attestation до gem push. Це дозволяє зберігати підпис у sigstore.dev
  • Bundler
    • Додано налаштування lockfile_checksums для включення контрольних сум у нові lockfile
    • Додано bundle lock --add-checksums, щоб додати контрольні суми до наявного lockfile
  • JSON

    • Покращення продуктивності JSON.parse приблизно у 1.5 раза швидше, ніж json-2.7.x.
  • Tempfile

    • Реалізовано ключовий аргумент anonymous: true для Tempfile.create. Tempfile.create(anonymous: true) одразу видаляє створений тимчасовий файл. Тож застосункам не потрібно видаляти файл. [Feature #20497]
  • win32/sspi.rb

Наступні bundled gems підвищено зі статусу default gems.

  • mutex_m 0.3.0
  • getoptlong 0.2.1
  • base64 0.2.0
  • bigdecimal 3.1.8
  • observer 0.1.2
  • abbrev 0.1.2
  • resolv-replace 0.1.1
  • rinda 0.2.0
  • drb 2.2.1
  • nkf 0.2.0
  • syslog 0.2.0
  • csv 3.3.2
  • repl_type_completor 0.1.9

Проблеми сумісності

  • Змінено повідомлення про помилки та відображення стеків викликів.
    • Як початкову лапку використовують одинарну лапку замість зворотної. [Feature #16495]
    • Перед назвою методу відображають назву класу (лише коли клас має постійну назву). [Feature #19117]
    • Методи Kernel#caller, Thread::Backtrace::Location тощо також змінено відповідно.
    Old:
    test.rb:1:in `foo': undefined method `time' for an instance of Integer
            from test.rb:2:in `<main>'
    
    New:
    test.rb:1:in 'Object#foo': undefined method 'time' for an instance of Integer
            from test.rb:2:in '<main>'
    
  • Змінено формат виводу Hash#inspect. [Bug #20433]

    • Ключі-символи відображаються з використанням сучасного синтаксису ключів символів: "{user: 1}"
    • Інші ключі тепер мають пробіли навколо =>: '{"user" => 1}', тоді як раніше їх не було: '{"user"=>1}'
  • Kernel#Float() тепер приймає десятковий рядок без дробової частини. [Feature #20705]

    Float("1.")    #=> 1.0 (раніше було виключення ArgumentError)
    Float("1.E-1") #=> 0.1 (раніше було виключення ArgumentError)
    
  • String#to_f тепер приймає десятковий рядок без дробової частини. Зверніть увагу, що результат змінюється, якщо вказано експоненту. [Feature #20705]

    "1.".to_f    #=> 1.0
    "1.E-1".to_f #=> 0.1 (раніше поверталося 1.0)
    
  • Refinement#refined_class було вилучено. [Feature #19714]

Проблеми сумісності стандартної бібліотеки

  • DidYouMean

    • DidYouMean::SPELL_CHECKERS[]= та DidYouMean::SPELL_CHECKERS.merge! вилучено.
  • Net::HTTP

    • Вилучено такі застарілі константи:
      • Net::HTTP::ProxyMod
      • Net::NetPrivate::HTTPRequest
      • Net::HTTPInformationCode
      • Net::HTTPSuccessCode
      • Net::HTTPRedirectionCode
      • Net::HTTPRetriableCode
      • Net::HTTPClientErrorCode
      • Net::HTTPFatalErrorCode
      • Net::HTTPServerErrorCode
      • Net::HTTPResponseReceiver
      • Net::HTTPResponceReceiver

      Ці константи були застарілими з 2012 року.

  • Timeout

    • Відхиляє від’ємні значення для Timeout.timeout. [Bug #20795]
  • URI

    • Парсер за замовчуванням перемкнено на сумісний з RFC 3986 замість RFC 2396. [Bug #19266]

Оновлення C API

  • rb_newobj та rb_newobj_of (і відповідні макроси RB_NEWOBJ, RB_NEWOBJ_OF, NEWOBJ, NEWOBJ_OF) вилучено. [Feature #20265]
  • Вилучено застарілу функцію rb_gc_force_recycle. [Feature #18290]

Інші зміни

  • Передавання блоку в метод, який не використовує переданий блок, показуватиме попередження в режимі verbose (-w). [Feature #15554]

  • Перевизначення деяких базових методів, які спеціально оптимізовані інтерпретатором та JIT, таких як String.freeze або Integer#+, тепер видає попередження про клас продуктивності (-W:performance або Warning[:performance] = true). [Feature #20429]

Детальніше див. NEWS або журнали комітів для подробиць.

Унаслідок цих змін 4942 файлів змінено, 202244 вставок(+), 255528 видалень(-) з часу Ruby 3.3.0!

З Різдвом, зі святами, і приємного програмування з Ruby 3.4!

Завантаження

  • https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.0.tar.gz

    SIZE: 23153022
    SHA1: 8ccb561848a7c460ae08e1a120a47c4a88a79335
    SHA256: 068c8523442174bd3400e786f4a6952352c82b1b9f6210fd17fb4823086d3379
    SHA512: bc70ecba27d1cdea00879f03487cad137a7d9ab2ad376cfb7a65780ad14da637fa3944eeeede2c04ab31eeafb970c64ccfeeb854c99c1093937ecc1165731562
    
  • https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.0.tar.xz

    SIZE: 17215572
    SHA1: eb25447cc404e8d2e177c62550d0224ebd410e68
    SHA256: 0081930db22121eb997207f56c0e22720d4f5d21264b5907693f516c32f233ca
    SHA512: 776a2cf3e9ccc77c27500240f168aa3e996b0c7c1ee1ef5a7afc291a06c118444016fde38b5b139c0b800496b8eb1b5456562d833f0edc0658917164763b1af7
    
  • https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.0.zip

    SIZE: 28310193
    SHA1: 26254ca5d3decc28a4e5faec255995265e5270b5
    SHA256: c120228038af04554f6363e716b0a32cbf53cf63c6adf9f2c22a24f43dc8b555
    SHA512: 4d535ed10db76a6aa74f8a025df319deb28483a7a781c24045906ee7663f1cff9d9f9e71dbc993c9e050113a34b37c7fa2143c355a0a6e1e1029bf2c92213ecc
    

Що таке Ruby

Ruby уперше розробив Matz (Yukihiro Matsumoto) у 1993 році, і зараз вона розвивається як Open Source. Вона працює на багатьох платформах і використовується по всьому світу, особливо для веброзробки.

Останні новини

Вийшов Ruby 4.0.0 preview3

Раді повідомити про вихід Ruby 4.0.0-preview3. Ruby 4.0 вводить Ruby::Box і “ZJIT” та додає багато покращень.

Опублікував naruse 18-12-2025

Вийшов Ruby 4.0.0 preview2

Раді повідомити про вихід Ruby 4.0.0-preview2. Ruby 4.0 оновлює версію Unicode до 17,0.0 тощо.

Опублікував naruse 17-11-2025

Більше новин...