发布者:naruse,于 2020 年 12 月 8 日
我们很高兴地宣布 Ruby 3.0.0-preview2 发布。
它引入了许多新特性和性能改进。
静态分析
RBS
RBS 是一种描述 Ruby 程序类型的语言。
包括 TypeProf 在内的类型检查器和其他支持 RBS 的工具,将通过 RBS 定义更好地理解 Ruby 程序。
您可以写下类和模块的定义:类中定义的方法、实例变量及其类型,以及继承/混入关系。
RBS 的目标是支持 Ruby 程序中常见的模式,它允许编写包括联合类型、方法重载和泛型在内的高级类型。它还支持具有接口类型的鸭子类型。
Ruby 3.0 附带 rbs
gem,它允许解析和处理用 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
有关更多详细信息,请参阅 rbs gem 的 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
您可以通过将输入保存为 “test.rb” 并调用名为 “typeprof test.rb” 的命令来运行 TypeProf。
您也可以在线尝试 TypeProf。(它在服务器端运行 TypeProf,如果它关闭了,请见谅!)
TypeProf 仍处于实验阶段,尚未完全成熟;仅支持 Ruby 语言的一个子集,并且类型错误的检测是有限的。但它仍在快速增长,以提高语言特性的覆盖范围、分析性能和可用性。欢迎任何反馈。
Ractor(实验性)
Ractor 是一种类似 Actor 模型的并发抽象,旨在提供并行执行功能,而无需担心线程安全问题。
您可以创建多个 ractor,并且可以并行运行它们。Ractor 使您能够创建线程安全的并行程序,因为 ractor 不能共享普通对象。ractor 之间的通信通过消息传递支持。
为了限制对象的共享,Ractor 对 Ruby 的语法引入了一些限制(如果没有多个 Ractor,则没有限制)。
规范和实现尚未成熟,将来可能会发生变化,因此此功能被标记为实验性,并在第一个 Ractor.new
时显示 “实验性功能” 警告。
以下小程序使用两个 ractor 并行计算 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.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
有关更多详细信息,请参阅 doc/ractor.md。
Fiber 调度器
引入了 Fiber#scheduler
来拦截阻塞操作。这允许在不更改现有代码的情况下实现轻量级并发。观看“别等我,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 请求:(解释一下:)- async 是外部 gem
- 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
其他值得注意的新功能
- 单行模式匹配现在使用
=>
而不是in
。# version 3.0 {a: 0, b: 1} => {a:} p a # => 0 # version 2.7 {a: 0, b: 1} in {a:} p a # => 0
- 添加了查找模式。
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}
- 内存视图作为实验性功能添加
- 这是一组新的 C-API,用于在扩展库之间交换原始内存区域,例如数字数组和位图图像。扩展库还可以共享内存区域的元数据,这些元数据由形状、元素格式等组成。使用这些类型的元数据,扩展库甚至可以适当地共享多维数组。此功能的设计参考了 Python 的缓冲协议。
性能改进
- MJIT 中实现了许多改进。有关详细信息,请参阅 NEWS。
- 将长代码粘贴到 IRB 的速度比 Ruby 2.7.0 捆绑的速度快 53 倍。例如,粘贴此示例代码所需的时间从 11.7 秒减少到 0.22 秒。
自 2.7 以来的其他显著变化
- 关键字参数与其他参数分离。
- 原则上,在 Ruby 2.7 上打印警告的代码将无法工作。有关详细信息,请参阅文档。
- 顺便说一句,参数转发现在支持前导参数。
def method_missing(meth, ...) send(:"do_#{ meth }", ...) end
$SAFE
功能已完全删除;现在它是一个普通的全局变量。- 回溯的顺序在 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
- 以下库不再是捆绑的 gem。安装相应的 gem 以使用这些功能。
- net-telnet
- xmlrpc
- 以下默认 gem 现在是捆绑的 gem。
- rexml
- rss
- 以下 stdlib 文件现在是默认 gem,并在 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
自 Ruby 2.7.0 以来,更改了 3776 个文件,插入了 181573 行代码(+),删除了 145096 行代码(-)!
请尝试 Ruby 3.0.0-preview2,并向我们提供任何反馈!
下载
-
https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-preview2.tar.gz
SIZE: 19378626 SHA1: 25363b20225850224e7835e99906c52f2ff57792 SHA256: 9de8661565c2b1007d91a580e9a7e02d23f1e8fc8df371feb15a2727aa05fd9a SHA512: 6fa4191425ae71e41894b60bd9c31d483a562ee8216886360ce18238ab48115b95be0367708612c45f634e7584fba8940a524ba0113ce0f36ce4df78a112d0b7
-
https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-preview2.tar.xz
SIZE: 14244252 SHA1: 54e4d3892ce480106382bd2d36dd7395e01b0f2a SHA256: 03078e82d4fb55c13837c69e56565fc49c451d11b1ca5e1b075d990d0957f181 SHA512: 8b0e6e3ba7e5f95586b4438d965e7b09187ad599f4ac22dec3db7b176358514fe0c0890dde8912fef1ef92ffcde3f6f1228178eabadcf3a05601e5b6f05881ae
-
https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-preview2.zip
SIZE: 23907144 SHA1: 064ee265c94b3df87e737622ba84437ea0d6aeaf SHA256: 19e295ae50934ddac2b366f0c7c8de9bd710d596b76eba02152f3641e5ce2b23 SHA512: 598def50ef9e8ae1f44e05ff2c4e35acf252437286f08644ba5e301ebff2db399140bafa72868877100d6ffa736a4474cb7b99ecea8bdf835ed113ab250bb3d9
什么是 Ruby
Ruby 最初由 Matz (Yukihiro Matsumoto) 于 1993 年开发,现在作为开源项目开发。它在多个平台上运行,并在世界各地广泛使用,尤其是在 Web 开发中。