Вийшов Ruby 3.2.0 Preview 3
Опублікував naruse 11-11-2022
Переклав: Andrii Furmanets
Ми раді оголосити випуск Ruby 3.2.0-preview3. Ruby 3.2 додає багато функцій та покращень продуктивності.
Підтримка WASI на основі WebAssembly
Це початковий порт підтримки WASI на основі WebAssembly. Це дозволяє бінарному файлу CRuby бути доступним у веб-браузері, середовищі Serverless Edge та інших вбудовувачах WebAssembly/WASI. Зараз цей порт проходить базові та bootstrap тестові набори, які не використовують Thread API.

Передісторія
WebAssembly (Wasm) спочатку введено для запуску програм безпечно та швидко у веб-браузерах. Але його мета - запуск програм ефективно з безпекою на різних середовищах - довго бажана не лише вебом, але й загальними додатками.
WASI (The WebAssembly System Interface) розроблено для таких випадків використання. Хоча такі додатки потребують спілкування з операційними системами, WebAssembly працює на віртуальній машині, яка не мала системного інтерфейсу. WASI стандартизує це.
Підтримка WebAssembly/WASI в Ruby має на меті використати ці проекти. Вона дозволяє розробникам Ruby писати додатки, які працюють на такій обіцяній платформі.
Випадок використання
Ця підтримка заохочує розробників використовувати CRuby в середовищі WebAssembly. Приклад випадку використання - підтримка CRuby TryRuby playground. Тепер ви можете спробувати оригінальний CRuby у вашому веб-браузері.
Технічні моменти
Сьогоднішні WASI та WebAssembly самі мають деякі відсутні функції для реалізації Fiber, винятків та GC, оскільки вони все ще розвиваються, а також з міркувань безпеки. Тому CRuby заповнює прогалину, використовуючи Asyncify, який є технікою бінарного перетворення для контролю виконання в userland.
Крім того, ми побудували VFS поверх WASI, щоб ми могли легко упакувати додатки Ruby в один .wasm файл. Це робить розповсюдження додатків Ruby трохи простішим.
Пов’язані посилання
Покращення Regexp проти ReDoS
Відомо, що зіставлення Regexp може зайняти несподівано довго. Якщо ваш код намагається зіставити можливо неефективний Regexp з ненадійним вводом, зловмисник може використати це для ефективної Denial of Service (так звана Regular expression DoS, або ReDoS).
Ми ввели два покращення, які значно пом’якшують ReDoS.
Покращений алгоритм зіставлення Regexp
З Ruby 3.2, алгоритм зіставлення Regexp значно покращено, використовуючи техніку мемоізації.
# Це зіставлення займає 10 сек. в Ruby 3.1, та 0.003 сек. в Ruby 3.2
/^a*b?a*$/ =~ "a" * 50000 + "x"
Покращений алгоритм зіставлення дозволяє більшості зіставлень Regexp (близько 90% у наших експериментах) завершуватися за лінійний час.
(Для користувачів preview: ця оптимізація може споживати пам’ять пропорційно довжині вводу для кожного зіставлення. Ми очікуємо, що практичних проблем не виникне, оскільки це виділення пам’яті зазвичай відкладене, і нормальне зіставлення Regexp повинно споживати максимум у 10 разів більше пам’яті, ніж довжина вводу. Якщо у вас закінчується пам’ять при зіставленні Regexps у реальному додатку, будь ласка, повідомте про це.)
Оригінальна пропозиція: https://bugs.ruby-lang.org/issues/19104
Regexp timeout
Оптимізація вище не може бути застосована до деяких видів регулярних виразів, таких як включення розширених функцій (наприклад, back-references або look-around), або з великою фіксованою кількістю повторень. Як запасна міра, також введено функцію таймауту для зіставлення Regexp.
Regexp.timeout = 1.0
/^a*b?a*()\1$/ =~ "a" * 50000 + "x"
#=> Regexp::TimeoutError піднімається за одну секунду
Зауважте, що Regexp.timeout є глобальною конфігурацією. Якщо ви хочете використовувати різні налаштування таймауту для деяких спеціальних Regexps, ви можете використати ключове слово timeout для Regexp.new.
Regexp.timeout = 1.0
# Цей regexp не має таймауту
long_time_re = Regexp.new('^a*b?a*()\1$', timeout: Float::INFINITY)
long_time_re =~ "a" * 50000 + "x" # ніколи не переривається
Оригінальна пропозиція: https://bugs.ruby-lang.org/issues/17837
Інші помітні нові функції
Більше не включати джерела 3-х сторін
-
Ми більше не включаємо джерела 3-х сторін, такі як
libyaml,libffi.-
Джерело libyaml було видалено з psych. Вам може знадобитися встановити
libyaml-devна платформі Ubuntu/Debian. Назва пакета відрізняється на кожній платформі. -
Включене джерело libffi також видалено з
fiddle
-
Мова
-
Анонімні rest та keyword rest аргументи тепер можуть передаватися як аргументи, замість просто використання в параметрах методу. [Функція #18351]
def foo(*) bar(*) end def baz(**) quux(**) end -
Proc, який приймає один позиційний аргумент та ключові слова, більше не буде автоплітуватися. [Помилка #18633]
proc{|a, **k| a}.call([1, 2]) # Ruby 3.1 та раніше # => 1 # Ruby 3.2 та пізніше # => [1, 2] -
Порядок оцінки присвоєння констант для констант, встановлених на явних об’єктах, зроблено узгодженим з порядком оцінки присвоєння одного атрибута. З цим кодом:
foo::BAR = bazfooтепер викликається передbaz. Аналогічно, для множинних присвоєнь до констант використовується порядок оцінки зліва направо. З цим кодом:foo1::BAR1, foo2::BAR2 = baz1, baz2Тепер використовується наступний порядок оцінки:
foo1foo2baz1baz2
-
Find pattern більше не є експериментальним. [Функція #18585]
-
Методи, які приймають rest параметр (як
*args) та бажають делегувати ключові аргументи черезfoo(*args), тепер повинні бути позначеніruby2_keywords(якщо це ще не так). Іншими словами, всі методи, які бажають делегувати ключові аргументи через*args, тепер повинні бути позначеніruby2_keywords, без винятку. Це зробить легшим перехід до інших способів делегації, коли бібліотека може вимагати Ruby 3+. Раніше прапорецьruby2_keywordsзберігався, якщо метод, що приймає, приймав*args, але це була помилка та неузгодженість. Хороша техніка для знаходження потенційно відсутніхruby2_keywords-
це запустити тестовий набір, для місця, де він не проходить, знайти останній метод, який повинен приймати ключові аргументи, використати
puts nil, caller, nilтам, та перевірити кожен метод/блок у ланцюжку викликів, який повинен делегувати ключові слова, правильно позначений якruby2_keywords. [Помилка #18625] [Помилка #16466]def target(**kw) end # Випадково працювало без ruby2_keywords в Ruby 2.7-3.1, ruby2_keywords # потрібен в 3.2+. Так само як (*args, **kwargs) або (...) були б потрібні на # обох #foo та #bar при міграції від ruby2_keywords. ruby2_keywords def bar(*args) target(*args) end ruby2_keywords def foo(*args) bar(*args) end foo(k: 1)
-
Покращення продуктивності
YJIT
- Підтримка arm64 / aarch64 на UNIX платформах.
- Збірка YJIT вимагає Rust 1.58.1+. [Функція #18481]
Інші помітні зміни з 3.1
- Hash
- Hash#shift тепер завжди повертає nil, якщо hash порожній, замість повернення значення за замовчуванням або виклику default proc. [Помилка #16908]
- MatchData
- MatchData#byteoffset додано. [Функція #13110]
- Module
- Module.used_refinements додано. [Функція #14332]
- Module#refinements додано. [Функція #12737]
- Module#const_added додано. [Функція #17881]
- Proc
- Proc#dup повертає екземпляр підкласу. [Помилка #17545]
- Proc#parameters тепер приймає ключове слово lambda. [Функція #15357]
- Refinement
- Refinement#refined_class додано. [Функція #12737]
- RubyVM::AbstractSyntaxTree
- Додано опцію
error_tolerantдляparse,parse_fileтаof. [Функція #19013]
- Додано опцію
- Set
- Set тепер доступний як вбудований клас без необхідності
require "set". [Функція #16989] Він зараз автозавантажується через константуSetабо викликEnumerable#to_set.
- Set тепер доступний як вбудований клас без необхідності
- String
- String#byteindex та String#byterindex додано. [Функція #13110]
- Оновлено Unicode до Версії 14.0.0 та Emoji Версії 14.0. [Функція #18037] (також застосовується до Regexp)
- String#bytesplice додано. [Функція #18598]
- Struct
- Клас Struct також може бути ініціалізований з ключовими аргументами
без
keyword_init: trueнаStruct.new[Функція #16806]
- Клас Struct також може бути ініціалізований з ключовими аргументами
без
Проблеми сумісності
Примітка: Виключаючи виправлення помилок функцій.
Видалені константи
Наступні застарілі константи видалено.
FixnumтаBignum[Функція #12005]Random::DEFAULT[Функція #17351]Struct::GroupStruct::Passwd
Видалені методи
Наступні застарілі методи видалено.
Dir.exists?[Функція #17391]File.exists?[Функція #17391]Kernel#=~[Функція #15231]Kernel#taint,Kernel#untaint,Kernel#tainted?[Функція #16131]Kernel#trust,Kernel#untrust,Kernel#untrusted?[Функція #16131]
Проблеми сумісності Stdlib
Psychбільше не включає джерела libyaml. Користувачі повинні встановити бібліотеку libyaml самостійно через систему пакетів. [Функція #18571]
Оновлення C API
Оновлені C API
Наступні API оновлено.
- Оновлення PRNG
rb_random_interface_tоновлено та версіоновано. Бібліотеки розширень, які використовують цей інтерфейс та зібрані для старіших версій. Також функціяinit_int32повинна бути визначена.
Видалені C API
Наступні застарілі API видалено.
- Змінна
rb_cData. - Функції “taintedness” та “trustedness”. [Функція #16131]
Оновлення стандартних бібліотек
-
SyntaxSuggest
- Функція
syntax_suggestранішеdead_endінтегрована в Ruby. [Функція #18159]
- Функція
-
ErrorHighlight
- Тепер він вказує аргумент(и) TypeError та ArgumentError
test.rb:2:in `+': nil can't be coerced into Integer (TypeError)
sum = ary[0] + ary[1]
^^^^^^
- Наступні default gems оновлено.
- RubyGems 3.4.0.dev
- bigdecimal 3.1.2
- bundler 2.4.0.dev
- cgi 0.3.2
- date 3.2.3
- error_highlight 0.4.0
- etc 1.4.0
- io-console 0.5.11
- io-nonblock 0.1.1
- io-wait 0.3.0.pre
- ipaddr 1.2.4
- json 2.6.2
- logger 1.5.1
- net-http 0.2.2
- net-protocol 0.1.3
- ostruct 0.5.5
- psych 5.0.0.dev
- reline 0.3.1
- securerandom 0.2.0
- set 1.0.3
- stringio 3.0.3
- syntax_suggest 0.0.1
- timeout 0.3.0
- Наступні включені gems оновлено.
- minitest 5.16.3
- net-imap 0.2.3
- rbs 2.6.0
- typeprof 0.21.3
- debug 1.6.2
- Наступні default gems тепер є bundled gems.
Див. NEWS або логи комітів для більше деталей.
З цими змінами, 2719 файлів змінено, 191269 додано(+), 120315 видалено(-) з Ruby 3.1.0!
Завантаження
-
https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.0-preview3.tar.gz
РОЗМІР: 20086542 SHA1: dafca8116d36ceaa32482ab38359768de8c3ae5e SHA256: c041d1488e62730d3a10dbe7cf7a3b3e4268dc867ec20ec991e7d16146640487 SHA512: 860634d95e4b9c48f18d38146dfbdc3c389666d45454248a4ccdfc3a5d3cd0c71c73533aabf359558117de9add1472af228d8eaec989c9336b1a3a6f03f1ae88 -
https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.0-preview3.tar.xz
РОЗМІР: 14799804 SHA1: c94e2add05502cb5c39afffc995b7c8f000f7df0 SHA256: d3f5619de544240d92a5d03aa289e71bd1103379622c523a0e80ed029a74b3bb SHA512: c1864e2e07c3711eaa17d0f85dfbcc6e0682b077782bb1c155315af45139ae66dc4567c73682d326975b0f472111eb0a70f949811cb54bed0b3a816ed6ac34df -
https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.0-preview3.zip
РОЗМІР: 24426893 SHA1: 346c051c4be7ab8d0b551fd2ff8169785697db62 SHA256: cf49aa70e7ebd8abebffd5e49cd3bd92e5b9f3782d587cc7ed88c98dd5f17069 SHA512: 4f22b5ea91be17ef5f68cf0acb1e3a226dcc549ad71cc9b40e623220087c4065ca9bea942710f668e5c94ca0323da8d2ccd565f95a9085c1a0e38e9c0543b22f
Що таке Ruby
Ruby вперше розроблено Matz (Yukihiro Matsumoto) у 1993 році, і зараз розробляється як Open Source. Він працює на кількох платформах та використовується по всьому світу, особливо для веб-розробки.
Останні новини
Вийшов Ruby 3.2.10
Вийшов Ruby 3.2.10.
Опублікував hsbt 14-01-2026
Вийшов Ruby 4.0.1
Вийшов Ruby 4.0.1.
Опублікував k0kubun 13-01-2026
Вийшов Ruby 4.0.0
Ми раді повідомити про випуск Ruby 4.0.0. Ruby 4.0 представляє “Ruby Box” та “ZJIT”, а також додає багато покращень.
Опублікував naruse 25-12-2025
Новий вигляд документації Ruby
Слідом за ре-дизайном ruby-lang.org, ми маємо більше новин, щоб відсвяткувати 30-річчя Ruby: docs.ruby-lang.org має повністю новий вигляд завдяки Aliki — новій темі за замовчуванням для...
Опублікував Stan Lo 23-12-2025