Источник изображения
Хорошие новости для разработчиков — вышел Ruby 3.0.0, новый релиз динамического объектно-ориентированного языка программирования. По словам его поклонников, в новую версию вошло лучшее от Perl, Java, Python, Smalltalk, Eiffel, Ada и Lisp.
Новая версия Ruby — восьмой значительный выпуск, который получил множество обновлений и улучшений. К слову, над третьей версией разработчики трудились около пяти лет. Ее особенности — высокая производительность, параллелизм и типизация.
Кстати, те же пять лет назад автор языка Юкихиро Мацумото (Yukihiro Matsumoto) предложил концепцию Ruby 3x3. Она подразумевает, что выпуск Ruby 3.0 станет возможным после того, как удастся добиться трехкратного прироста производительности по сравнению с версией 2.0. В последнем релизе этого удалось добиться благодаря усовершенствованию поддержки JIT-компиляции.
Что нового?
- Разработчики добавили большое количество улучшений в MJIT. Например, увеличена производительность при таких рабочих нагрузках, как игры (тест Optcarrot), AI (тест Rubykon). Аналогичным образом увеличена производительность для любых приложений, где большая часть времени тратится на многократный вызов нескольких методов. Кроме того, снижен и размер кода, который генерируется компилятором. Речь о JIT-компиляторе, который, правда, еще не готов для оптимизации приложений, использующих фреймворк Rails. В этом случае охватывается большое количество методов, что приводит к неэффективной работе кэша i-cache.
- Появился инструментарий для аннотации типов RBS, поддерживающий большинство популярных шаблонов в программах на языке Ruby. Аннотации RBS дают возможность выполнять статический анализ кода без явного определения типов. Также предоставляются средства для описания определений классов и модулей: методы, определенные в классе, переменные экземпляра и их типы, а также иерархия наследования или подмешивания модулей. Плюс ко всему, появился экспериментальный анализатор типов TypeProf, который читает код, анализирует использование методов и генерирует прототип аннотаций типов в формате RBS.
module ChatApp
VERSION: String
class Channel
attr_reader name: String
attr_reader messages: Array[Message]
attr_reader users: Array[User | Bot] # `|` means union types, `User` or `Bot`.
def initialize: (String) -> void
def post: (String, from: User | Bot) -> Message # Method overloading is supported.
| (File, from: User | Bot) -> Message
end
end
- Добавлена экспериментальная поддержка модели акторов Ractor. Она предоставляет абстракцию, которая разработана для обеспечения потокобезопасного параллельного выполнения программы. Сообщается, что поддерживается создание нескольких ракторов, а также их параллельный запуск. Между собой ракторы взаимодействуют путем передачи сообщений.
require 'prime'
# n.prime? with sent integers in r1, r2 run in parallel
r1, r2 = *(1..2).map do
Ractor.new do
n = Ractor.recv
n.prime?
end
end
# send parameters
r1.send 2**61 - 1
r2.send 2**61 + 15
# wait for the results of expr1, expr2
p r1.take #=> true
p r2.take #=> true
- Появился планировщик легковесных fiber-потоков Fiber#scheduler, поддерживающий перехват блокирующих операций для обеспечения легкого параллелизма, не требующего изменения существующего кода. Вот классы и методы, которые поддерживаются:
— Mutex#lock, Mutex#unlock, Mutex#sleep
— ConditionVariable#wait
— Queue#pop, SizedQueue#push
— Thread#join
— Kernel#sleep
— Process.wait
— IO#wait, IO#read, IO#write и связанные с ними методы
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
- Подверглись переработке однострочники сопоставления с образцом «Добавление оператора — значение-переменная», что используется для правостороннего присваивания значений.
0 => a
p a #=> 0
{b: 0, c: 1} => {b:}
p b #=> 0
Кроме того, изменено и поведение «in», теперь он возвращает true или false.
# version 3.0
0 in 1 #=> false
# version 2.7
0 in 1 #=> raise NoMatchingPatternError
Добавлен экспериментальный шаблон для поиска значений:
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
- Добавлен метод Hash#except.
h = { a: 1, b: 2, c: 3 }
p h.except(:a) #=> {:b=>2, :c=>3}
- Появилась поддержка однострочного определения метода без использования ключевого слова «end».
def square(x) = x * x
- Также разработчики добавили экспериментальный C-API для обмена областями памяти между библиотеками-расширениями и предоставления метаданных о содержимом памяти.
- Увеличена производительность интерактивного интерпретатора IRB. Сообщается, что вставка больших участков кода производится в 53 (!) раза быстрее, чем в Ruby 2.7.
- Обновлены важные gem-модули, являющиеся частью stdlib.
Автор: Seleditor