Вийшов Ruby 3.0.0 Preview 2

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

Ми раді оголосити випуск Ruby 3.0.0-preview2.

Він вводить ряд нових функцій та покращень продуктивності.

Статичний аналіз

RBS

RBS - це мова для опису типів програм Ruby.

Перевірки типів, включаючи TypeProf та інші інструменти, що підтримують RBS, зрозуміють програми Ruby набагато краще з визначеннями RBS.

Ви можете записати визначення класів та модулів: методи, визначені в класі, змінні екземпляра та їх типи, та відносини наслідування/міксину.

Мета RBS - підтримувати загальні патерни в програмах Ruby, і він дозволяє писати розширені типи, включаючи об’єднані типи, перевантаження методів та дженерики. Він також підтримує duck typing з типами інтерфейсів.

Ruby 3.0 постачається з gem rbs, який дозволяє парсити та обробляти визначення типів, написані в RBS. Наступний приклад - невеликий приклад RBS з визначеннями класу, модуля та константи.

module ChatApp
  VERSION: String
  class Channel
    attr_reader name: String
    attr_reader messages: Array[Message]
    attr_reader users: Array[User | Bot]              # `|` означає об'єднані типи, `User` або `Bot`.
    def initialize: (String) -> void
    def post: (String, from: User | Bot) -> Message   # Підтримується перевантаження методів.
            | (File, from: User | Bot) -> Message
  end
end

Див. README gem rbs для більше деталей.

TypeProf

TypeProf - це інструмент аналізу типів, включений в пакет Ruby.

Зараз TypeProf служить як вид виведення типів.

Він читає звичайний (без анотацій типів) код Ruby, аналізує, які методи визначені та як вони використовуються, та генерує прототип підпису типу в форматі RBS.

Ось простий демо TypeProf.

Приклад вводу:

# test.rb
class User
  def initialize(name:, age:)
    @name, @age = name, age
  end
  attr_reader :name, :age
end
User.new(name: "John", age: 20)

Приклад виводу:

$ typeprof test.rb
# Classes
class User
  attr_reader name : String
  attr_reader age : Integer
  def initialize : (name: String, age: Integer) -> [String, Integer]
end

Ви можете запустити TypeProf, зберегши ввід як “test.rb” та викликавши команду “typeprof test.rb”.

Ви також можете спробувати TypeProf онлайн. (Він запускає TypeProf на стороні сервера, тому вибачте, якщо він недоступний!)

Див. документацію та демо для деталей.

TypeProf експериментальний і ще не так дозрілий; підтримується лише підмножина мови Ruby, і виявлення помилок типів обмежене. Але він все ще швидко розвивається для покращення покриття мовних функцій, продуктивності аналізу та зручності використання. Будь-який відгук дуже вітається.

Ractor (експериментально)

Ractor - це абстракція конкурентності, подібна до Actor-моделі, розроблена для надання функції паралельного виконання без проблем з потокобезпекою.

Ви можете створити кілька ractor та запустити їх паралельно. Ractor дозволяє вам створювати потокобезпечні паралельні програми, оскільки ractor не можуть ділитися звичайними об’єктами. Комунікація між ractor підтримується передачею повідомлень.

Щоб обмежити обмін об’єктами, Ractor вводить кілька обмежень до синтаксису Ruby (без кількох Ractor немає обмежень).

Специфікація та реалізація не дозріли та можуть змінитися в майбутньому, тому ця функція позначена як експериментальна та показує попередження про “експериментальну функцію”, коли створюється перший Ractor.new.

Наступна невелика програма обчислює n.prime? (n відносно велике ціле число) паралельно з двома ractor. Ви підтвердите, що виконання програми приблизно в 2 рази швидше порівняно з послідовною програмою на паралельному комп’ютері.

require 'prime'
# n.prime? з надісланими цілими числами в r1, r2 працюють паралельно
r1, r2 = *(1..2).map do
  Ractor.new do
    n = Ractor.recv
    n.prime?
  end
end
# надіслати параметри
r1.send 2**61 - 1
r2.send 2**61 + 15
# чекати результати expr1, expr2
p r1.take #=> true
p r2.take #=> true

Див. doc/ractor.md для більше деталей.

Fiber Scheduler

Fiber#scheduler введено для перехоплення блокуючих операцій. Це дозволяє легку конкурентність без зміни існуючого коду. Перегляньте “Don’t Wait For Me, Scalable Concurrency for Ruby 3” для огляду того, як це працює.

Зараз підтримуються класи/методи:

  • Mutex#lock, Mutex#unlock, Mutex#sleep
  • ConditionVariable#wait
  • Queue#pop, SizedQueue#push
  • Thread#join
  • Kernel#sleep
  • Process.wait
  • IO#wait, IO#read, IO#write та пов’язані методи (наприклад, #wait_readable, #gets, #puts тощо).
  • IO#select не підтримується. (Пояснити Async gem з посиланнями). Ця прикладна програма виконає кілька HTTP запитів одночасно:

(Пояснити це:)

  1. async - це зовнішній gem
  2. async використовує цю нову функцію
require 'async'
require 'net/http'
require 'uri'
Async do
  ["ruby", "python", "c"].each do |topic|
    Async do
      Net::HTTP.get(URI "https://www.google.com/search?q=#{topic}")
    end
  end
end

Інші помітні нові функції

  • Однолінійний pattern matching тепер використовує => замість in.
      # версія 3.0
      {a: 0, b: 1} => {a:}
      p a # => 0
      # версія 2.7
      {a: 0, b: 1} in {a:}
      p a # => 0
    
  • Додано find pattern.
      case ["a", 1, "b", "c", 2, "d", "e", "f", 3]
      in [*pre, String => x, String => y, *post]
        p pre  #=> ["a", 1]
        p x    #=> "b"
        p y    #=> "c"
        p post #=> [2, "d", "e", "f", 3]
      end
    
  • Додано нескінченне визначення методу.
      def square(x) = x * x
    
  • Hash#except тепер вбудований.
      h = { a: 1, b: 2, c: 3 }
      p h.except(:a) #=> {:b=>2, :c=>3}
    
  • Memory view додано як експериментальну функцію
    • Це новий набір C-API для обміну сирою областю пам’яті, такою як числовий масив та растрове зображення, між бібліотеками розширень. Бібліотеки розширень можуть також ділитися метаданими області пам’яті, що складається з форми, формату елемента тощо. Використовуючи такі метадані, бібліотеки розширень можуть навіть правильно ділитися багатовимірним масивом. Ця функція розроблена з посиланням на buffer protocol Python.

Покращення продуктивності

  • Багато покращень було реалізовано в MJIT. Див. NEWS детально.
  • Вставлення довгого коду в IRB у 53 рази швидше, ніж включено в Ruby 2.7.0. Наприклад, час, необхідний для вставлення цього прикладу коду, зменшується з 11.7 секунд до 0.22 секунди.

Інші помітні зміни з 2.7

  • Ключові аргументи розділені від інших аргументів.
    • В принципі, код, який виводить попередження на Ruby 2.7, не працюватиме. Див. документ детально.
    • До речі, пересилання аргументів тепер підтримує початкові аргументи.
      def method_missing(meth, ...)
        send(:"do_#{ meth }", ...)
      end
      
  • Функція $SAFE була повністю видалена; тепер це звичайна глобальна змінна.
  • Порядок backtrace був зворотний в Ruby 2.5, і відкочений назад. Тепер він поводиться як Ruby 2.4; повідомлення про помилку та номер рядка, де виникає виняток, виводяться спочатку, а його викликачі виводяться пізніше.
  • Деякі стандартні бібліотеки оновлено.
    • RubyGems 3.2.0.rc.1
    • Bundler 2.2.0.rc.1
    • IRB 1.2.6
    • Reline 0.1.5
  • Наступні бібліотеки більше не є включеними gems. Встановіть відповідні gems для використання цих функцій.
    • net-telnet
    • xmlrpc
  • Наступні default gems тепер є bundled gems.
    • rexml
    • rss
  • Наступні файли stdlib тепер є default gems та опубліковані на rubygems.org.
    • abbrev
    • base64
    • English
    • erb
    • find
    • io-nonblock
    • io-wait
    • net-ftp
    • net-http
    • net-imap
    • net-protocol
    • nkf
    • open-uri
    • optparse
    • resolv
    • resolv-replace
    • rinda
    • securerandom
    • set
    • shellwords
    • tempfile
    • time
    • tmpdir
    • tsort
    • weakref

Див. NEWS або логи комітів для більше деталей.

З цими змінами, 3776 файлів змінено, 181573 додано(+), 145096 видалено(-) з Ruby 2.7.0!

Будь ласка, спробуйте Ruby 3.0.0-preview2 та надішліть нам будь-який відгук!

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

  • https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-preview2.tar.gz

    РОЗМІР: 19378626
    SHA1: 25363b20225850224e7835e99906c52f2ff57792
    SHA256: 9de8661565c2b1007d91a580e9a7e02d23f1e8fc8df371feb15a2727aa05fd9a
    SHA512: 6fa4191425ae71e41894b60bd9c31d483a562ee8216886360ce18238ab48115b95be0367708612c45f634e7584fba8940a524ba0113ce0f36ce4df78a112d0b7
    
  • https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-preview2.tar.xz

    РОЗМІР: 14244252
    SHA1: 54e4d3892ce480106382bd2d36dd7395e01b0f2a
    SHA256: 03078e82d4fb55c13837c69e56565fc49c451d11b1ca5e1b075d990d0957f181
    SHA512: 8b0e6e3ba7e5f95586b4438d965e7b09187ad599f4ac22dec3db7b176358514fe0c0890dde8912fef1ef92ffcde3f6f1228178eabadcf3a05601e5b6f05881ae
    
  • https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-preview2.zip

    РОЗМІР: 23907144
    SHA1: 064ee265c94b3df87e737622ba84437ea0d6aeaf
    SHA256: 19e295ae50934ddac2b366f0c7c8de9bd710d596b76eba02152f3641e5ce2b23
    SHA512: 598def50ef9e8ae1f44e05ff2c4e35acf252437286f08644ba5e301ebff2db399140bafa72868877100d6ffa736a4474cb7b99ecea8bdf835ed113ab250bb3d9
    

Що таке Ruby

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

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

Вийшов 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

Вийшов Ruby 4.0.0 preview3

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

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

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