Опубликовал naruse 20-12-2020
Перевел: nakilon
Мы рады объявить о выходе Ruby 3.0.0-rc1.
В нем представлено много новых фич и улучшений производительности.
Статический анализ
RBS
RBS – это язык описания типов в программах на Ruby.
Тайп-чекеры, включая TypeProf и другие инструменты, поддерживающие RBS, будут понимать программы на Ruby намного лучше с определениями RBS.
Вы можете написать определения классам и модулям: методам, определенным в классе, переменным экземпляра и их типам, а также отношениям наследования/примесей.
RBS преследует цель поддержать наиболее часто встречающиеся паттерны программирования на Ruby и позволяет описывать сложные типы, такие как объединения, перегрузка методов и дженерики. Также поддерживается утиная типизация с интерфейсами.
Ruby 3.0 поставляется с гемом rbs
, который позволяет парсить и обрабатывать определения типов, написанные на языке RBS.
Ниже небольшой пример 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
См. README гема.
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, и определение типов ограничено. Однако она быстро растет и улучшает покрытие фич языка, скорость анализа и удобство использования. Любая обратная связь крайне приветствуется.
Рактор (экспериментально)
Рактор – это абстракция параллельных вычислений, подобная модели акторов, предназначенная обеспечить параллельное выполнение без лишних хлопот о потоковой безопасности.
Вы можете создать несколько ракторов и запустить их параллельно. Рактор обеспечивает потоковую безопасность параллельных вычислений тем, что не может иметь общих объектов с другими ракторами в обычном понимании. Коммуникация между ракторами обеспечивается передачей сообщений.
Рактор синтаксически ограничивает возможность совместного использования объектов (в случае одного Рактора разницы не будет).
Спецификация и реализация еще не окончательны и могут быть изменены в будущем, поэтому эта фича отмечена как экспериментальная и выдает предупреждение “experimental feature” при первом вызове Ractor.new
.
Ниже небольшая программа, вычисляющая n.prime?
(n
– относительно большое целое число) параллельно двумя ракторами. На компьютере, поддерживающем параллельные вычисления, вы убедитесь, что программа выполняется примерно в 2 раза быстрее, чем последовательная.
require 'prime'
# n.prime? with sent integers in r1, r2 run in parallel
r1, r2 = *(1..2).map do
Ractor.new do
n = Ractor.receive
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
См. doc/ractor.md.
Планировщик нитей
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
не поддерживается.
Следующий пример выполнит несколько запросов HTTP параллельно:
(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
Другие значимые новые фичи
-
Однострочный поиск по образцу изменил свой вид. (экспериментально)
-
добавлен
=>
для правостороннего присваивания.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
-
Добавлена возможность объявления метода без end.
def square(x) = x * x
-
Hash#except
теперь в stdlib.h = { a: 1, b: 2, c: 3 } p h.except(:a) #=> {:b=>2, :c=>3}
-
Просмотр памяти добавлен как экспериментальная фича
- Это новое C-API для прямого обмена участками памяти, такими как числовой массив или битмап, между библиотеками нативных расширений. Библиотеки расширений также могут делиться метаданными об участках памяти, таких как форма, формат и пр. С помощью этих метаданных библиотеки расширений могут делиться даже многомерными массивами. Дизайн этой фичи был вдохновлен буферным протоколом 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
- Поиск по образцу (
case
/in
) – больше не экспериментальная фича. - Фича
$SAFE
полностью выпилена; теперь это обычная глобальная переменная. - В Ruby 2.5 бектрейс был развернут, но это изменение откатили. Теперь он ведет себя как в Ruby 2.4; сначала идет сообщение об ошибке и номер строки, где возникло исключение, а затем следует стек вызовов.
- Обновлены некоторые стандартные библиотеки.
- RubyGems 3.2.2
- Bundler 2.2.2
- IRB 1.2.6
- Reline 0.1.5
- Psych 3.2.1
- JSON 2.4.1
- BigDecimal 3.0.0
- CSV 3.1.9
- Digest 3.0.0
- Fiddle 1.0.4
- StringIO 3.0.0
- StringScanner 3.0.0
- Следующие библиотеки более не поставляются с языком.
Устанавливайте их соответствующими гемами.
- net-telnet
- xmlrpc
- Следующие, поставляемые с языком, гемы больше не встроены в него.
- rexml
- rss
- Следующие файлы стандартной библиотеки переведены в разряд встроенных гемов и опубликованы на rubygems.org.
- English
- abbrev
- base64
- drb
- debug
- erb
- find
- net-ftp
- net-http
- net-imap
- net-protocol
- open-uri
- optparse
- pp
- prettyprint
- resolv-replace
- resolv
- rinda
- set
- securerandom
- shellwords
- tempfile
- tmpdir
- time
- tsort
- un
- weakref
- digest
- io-nonblock
- io-wait
- nkf
- pathname
- syslog
- win32ole
В ходе этого со времен версии 2.7.0 было изменено 3889 файлов, было сделано 195560 вставок(+), 152740 удалений(-)!
Пожалуйста, попробуйте Ruby 3.0.0-rc1 и дайте обратную связь!
Скачать
-
https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-rc1.tar.gz
SIZE: 19488885 SHA1: 34ede2128a90ef3217d9cab9efcdf20fc444f67c SHA256: e1270f38b969ce7b124f0a4c217e33eda643f75c7cb20debc62c17535406e37f SHA512: 798926db82d27366b39be97556ac5cb322986b96df913c398449bd3ece533e484a3047fe35e7a6241dfbd0f7da803438f5b04b805b33f95c73e3e41d0bb51183
-
https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-rc1.tar.xz
SIZE: 14341128 SHA1: deff34cf67373dca166e9961051b6c4723aaaec6 SHA256: f1adda082f9291e394d25ed32975abbef90962dc4c8b11130586a0151558e79a SHA512: f4f13dbfa1c96088eb3dbfba0cb1fe99f4e17197ee2d4b78fbe16496780797a10daa3f2ff9c38d2d7b316974101eccf45184708ad05491fb49898b3a7cc6d673
-
https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-rc1.zip
SIZE: 23902334 SHA1: e3e20b4d0ec895e579ae416f2b7552c6be3596f7 SHA256: 25ced95fa544af6a64d348dc5eace008edfda22f55ed1f6ad9f932b344e6196d SHA512: c81b3bf7ce582bf39fd7bc1e691d0777ed4cf38ca6b4d54bc9edaef076ae8bcecb6a86ebfd773591f7d8533e772517033c762d35fdc8b05cb4db4488c2bacec2
Что такое Ruby
Matz (Yukihiro Matsumoto) разработал первую версию Ruby в 1993, и на сегодня язык разрабатывается как Open Source. Он работает на множестве платформ и используется по всему миру, особенно в веб разработке.