NEWS for Ruby 3.0.0¶ ↑
本文档列出了自 2.7.0 版本以来,除错误修复之外的用户可见功能变更。
请注意,每个条目都保持在最小限度,详情请参阅链接。
语言变更¶ ↑
-
关键字参数现在与位置参数分离。在 Ruby 2.7 中导致弃用警告的代码现在将导致
ArgumentError
或不同的行为。[Feature #14183] -
接受单个剩余参数和关键字的 Proc 不再受自动展开的影响。这现在与接受单个剩余参数且没有关键字的 Proc 的行为相匹配。[Feature #16166]
pr = proc{|*a, **kw| [a, kw]} pr.call([1]) # 2.7 => [[1], {}] # 3.0 => [[[1]], {}] pr.call([1, {a: 1}]) # 2.7 => [[1], {:a=>1}] # and deprecation warning # 3.0 => [[[1, {:a=>1}]], {}]
-
参数转发 (
...
) 现在支持前导参数。[Feature #16378]def method_missing(meth, ...) send(:"do_#{meth}", ...) end
-
模式匹配 (
case/in
) 不再是实验性的。[Feature #17260] -
单行模式匹配已重新设计。[实验性]
-
添加了
=>
。它可以像向右赋值一样使用。[Feature #17260]0 => a p a #=> 0 {b: 0, c: 1} => {b:} p b #=> 0
-
in
被更改为返回true
或false
。[Feature #17371]# version 3.0 0 in 1 #=> false # version 2.7 0 in 1 #=> raise NoMatchingPatternError
-
-
添加了查找模式。[实验性] [Feature #16828]
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
-
添加了无尽方法定义。[实验性] [Feature #16746]
def square(x) = x * x
-
当使用
# frozen-string-literal: true
时,内插的String
字面量不再被冻结。[Feature #17104] -
添加了魔术注释
shareable_constant_value
来冻结常量。有关更多详细信息,请参阅魔术注释。[Feature #17273] -
引入了静态分析基础。
-
默认情况下不再显示弃用警告(自 Ruby 2.7.2 起)。使用
-W:deprecated
(或使用-w
来显示其他警告)来开启它们。[Feature #16345] -
$SAFE
和$KCODE
现在是普通的全局变量,没有特殊行为。与$SAFE
相关的 C-API 方法已被删除。[Feature #16131] [Feature #17136] -
在方法中的单例类定义中 yield 现在是
SyntaxError
而不是警告。方法之外的类定义中的 yield 现在是SyntaxError
而不是LocalJumpError
。[Feature #15575] -
当一个类变量被祖先类/模块中的相同定义覆盖时,现在会引发
RuntimeError
(以前,它只在详细模式下发出警告)。此外,从顶层作用域访问类变量现在是一个RuntimeError
。[Bug #14541] -
给编号参数赋值现在是一个
SyntaxError
而不是警告。
命令行选项¶ ↑
--help
选项¶ ↑
当环境变量 RUBY_PAGER
或 PAGER
存在并且具有非空值,并且标准输入和输出是 tty 时,--help
选项会通过该值指定的寻呼机显示帮助消息。[Feature #16754]
--backtrace-limit
选项¶ ↑
--backtrace-limit
选项限制回溯的最大长度。[Feature #8661]
核心类更新¶ ↑
仅限突出显示的更新。
-
-
可以使用
Enumerator::ArithmeticSequence
进行切片dirty_data = ['--', 'data1', '--', 'data2', '--', 'data3'] dirty_data[(1..).step(2)] # take each second element # => ["data1", "data2", "data3"]
-
-
当使用一个参数调用
Binding#eval
时,将在评估的代码中使用"(eval)"
作为__FILE__
,并使用1
作为__LINE__
。[Bug #4352] [Bug #17419]
-
-
ConditionVariable
-
ConditionVariable#wait 现在可以在非阻塞上下文中调用
block
/unblock
调度程序钩子。[Feature #16786]
-
-
-
Dir.glob
和Dir.[]
现在默认按结果排序,并接受sort:
关键字选项。[Feature #8709]
-
-
-
添加了
ENV.except
,它返回一个排除给定键及其值的哈希。[Feature #15822] -
Windows: 将
ENV
名称和值作为 UTF-8 编码的字符串读取。[Feature #12650]
-
-
-
添加了新的编码 IBM720。[Feature #16233]
-
将 Windows 上
Encoding.default_external
的默认值更改为 UTF-8 [Feature #16604]
-
-
-
Fiber.new
(blocking: true/false) 允许您创建非阻塞执行上下文。[Feature #16786] -
Fiber#blocking?
可以判断光纤是否是非阻塞的。[Feature #16786] -
Fiber#backtrace
和Fiber#backtrace_locations
提供每个光纤的回溯。[Feature #16815] -
放宽了对
Fiber#transfer
的限制。[Bug #17221]
-
-
-
添加了 GC.auto_compact= 和 GC.auto_compact 来控制何时运行压缩。将
auto_compact=
设置为true
将导致在主要收集期间进行压缩。目前,压缩会给主要收集增加显著的开销,所以请先进行测试![Feature #17176]
-
-
-
Hash#transform_keys
和Hash#transform_keys!
现在接受将键映射到新键的哈希。[Feature #16274] -
添加了
Hash#except
,它返回一个排除给定键及其值的哈希。[Feature #15822]
-
-
-
IO#nonblock? 现在默认为
true
。[Feature #16786] -
IO#wait_readable
、IO#wait_writable
、IO#read
、IO#write
和其他相关方法(例如IO#puts
、IO#gets
)可能会在非阻塞执行上下文中调用调度程序钩子#io_wait(io, events, timeout)
。[Feature #16786]
-
-
-
当使用
freeze: false
关键字调用Kernel#clone
时,将使用freeze: false
关键字调用#initialize_clone
。[Bug #14266] -
当使用
freeze: true
关键字调用Kernel#clone
时,将使用freeze: true
关键字调用#initialize_clone
,并且即使接收者未冻结,也会返回冻结的副本。[Feature #16175] -
当使用两个参数调用
Kernel#eval
时,将在评估的代码中使用"(eval)"
作为__FILE__
,并使用1
作为__LINE__
。[Bug #4352] -
如果调用
Kernel#lambda
时没有字面量块,现在会发出警告。[Feature #15973] -
Kernel.sleep
在非阻塞执行上下文中调用调度程序钩子#kernel_sleep(...)
。[Feature #16786]
-
-
-
Module#include
和Module#prepend
现在会影响已经包含或预先考虑了接收者的类和模块,如果参数在其他模块和类包含或预先考虑了接收者之前包含在接收者中,则会镜像该行为。[Feature #9573]class C; end module M1; end module M2; end C.include M1 M1.include M2 p C.ancestors #=> [C, M1, M2, Object, Kernel, BasicObject]
-
Module#public
、Module#protected
、Module#private
、Module#public_class_method
、Module#private_class_method
、顶层 “private” 和 “public” 方法现在接受带有方法名称列表的单个数组参数。[Feature #17314] -
Module#attr_accessor
、Module#attr_reader
、Module#attr_writer
和Module#attr
方法现在返回一个符号的已定义方法名称数组。[Feature #17314] -
Module#alias_method
现在将返回定义的别名作为符号。 [特性 #17314]
-
-
互斥锁 (Mutex)
-
Mutex
现在是按Fiber
而不是按Thread
获取的。此更改应与几乎所有用法兼容,并避免在使用调度器时发生阻塞。 [特性 #16792]
-
-
队列 (Queue) / 大小限制队列 (SizedQueue)
-
Queue#pop、SizedQueue#push 和相关方法现在可能会在非阻塞上下文中调用
block
/unblock
调度器钩子。 [特性 #16786]
-
-
-
添加了新类以启用并行执行。有关更多详细信息,请参阅 ractor.md。
-
-
-
Symbol#to_proc
现在返回一个 lambdaProc
。 [特性 #16260] -
添加了
Symbol#name
,如果符号已命名,它将返回符号的名称。返回的字符串是冻结的。 [特性 #16150]
-
-
-
引入
Fiber.set_scheduler
用于拦截阻塞操作,以及Fiber.scheduler
用于访问当前调度器。有关支持的操作以及如何实现调度器钩子的更多详细信息,请参阅 fiber.md。 [特性 #16786] -
Fiber.blocking?
指示当前执行上下文是否正在阻塞。 [特性 #16786] -
Thread#join
在非阻塞执行上下文中调用调度器钩子block
/unblock
。 [特性 #16786]
-
-
-
添加了
Thread.ignore_deadlock
访问器以禁用默认的死锁检测,从而允许使用信号处理程序来中断死锁。 [错误 #13768]
-
-
-
Warning#warn
现在支持 category 关键字参数。 [特性 #17122]
-
标准库更新¶ ↑
仅限突出显示的更新。
-
BigDecimal
-
更新到 BigDecimal 3.0.0
-
此版本与
Ractor
兼容。
-
-
Bundler
-
更新到 Bundler 2.2.3
-
-
CGI
-
更新到 0.2.0
-
此版本与
Ractor
兼容。
-
-
CSV
-
更新到 CSV 3.1.9
-
-
Date
-
更新到 Date 3.1.1
-
此版本与
Ractor
兼容。
-
-
Digest
-
更新到 Digest 3.0.0
-
此版本与
Ractor
兼容。
-
-
Etc
-
更新到 Etc 1.2.0
-
此版本与
Ractor
兼容。
-
-
Fiddle
-
更新到 Fiddle 1.0.5
-
-
IRB
-
更新到 IRB 1.2.6
-
-
JSON
-
更新到 JSON 2.5.0
-
此版本与
Ractor
兼容。
-
-
Set
-
更新到 set 1.0.0
-
由于依赖关系和性能原因,已删除 SortedSet。
-
添加 Set#join 作为
.to_a.join
的简写。 -
添加了 Set#<=>。
-
-
Socket
-
将 :connect_timeout 添加到 TCPSocket.new [特性 #17187]
-
-
Net::HTTP
-
Net::SMTP
-
添加 SNI 支持。
-
Net::SMTP.start 参数是关键字参数。
-
TLS 默认情况下不应检查主机名。
-
-
OpenStruct
-
Pathname
-
与
Ractor
兼容。
-
-
Psych
-
更新到 Psych 3.3.0
-
此版本与
Ractor
兼容。
-
-
Reline
-
更新到 Reline 0.1.5
-
-
RubyGems
-
更新到 RubyGems 3.2.3
-
-
StringIO
-
更新到 StringIO 3.0.0
-
此版本与
Ractor
兼容。
-
-
StringScanner
-
更新到 StringScanner 3.0.0
-
此版本与
Ractor
兼容。
-
-
URI
-
已删除 URI.escape 和 URI.unescape。请改为根据您的具体用例使用以下方法。
-
CGI.escape
-
URI.encode_www_form
-
URI.encode_www_form_component
-
CGI.unescape
-
URI.decode_www_form
-
URI.decode_www_form_component
-
-
兼容性问题¶ ↑
不包括功能性错误修复。
-
Regexp
字面量和所有Range
对象都是冻结的。 [特性 #8948] [特性 #16377] [特性 #15504]/foo/.frozen? #=> true (42...).frozen? # => true
-
实验性:
Hash#each
始终生成一个包含 2 个元素的数组。 [错误 #12706]-
现在
{ a: 1 }.each(&->(k, v) { })
由于 lambda 的参数数量检查而引发ArgumentError
。
-
-
当写入重定向到关闭管道的 STDOUT 时,现在不会显示断管错误消息。 [特性 #14413]
-
不再定义
TRUE
/FALSE
/NIL
常量。 -
Integer#zero?
为了优化,覆盖了Numeric#zero?
。 [杂项 #16961] -
当传递
Regexp
且没有块时,Enumerable#grep
和Enumerable#grep_v
不再修改Regexp.last_match
。 [错误 #17030] -
要求“open-uri”不再重新定义
Kernel#open
。请直接调用URI.open
或改用use URI#open
。 [杂项 #15893] -
由于依赖关系和性能原因,已删除 SortedSet。
标准库兼容性问题¶ ↑
-
默认 gem
-
以下库从标准库升级为默认 gem。
-
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
-
-
以下扩展从标准库升级为默认 gem。
-
digest
-
io-nonblock
-
io-wait
-
nkf
-
pathname
-
syslog
-
win32ole
-
-
-
捆绑 gem
-
已从捆绑 gem 中删除 net-telnet 和 xmlrpc。如果您有兴趣维护它们,请在 github.com/ruby/xmlrpc 或 github.com/ruby/net-telnet 上评论您的计划。
-
-
已从 Ruby 标准库中删除 SDBM。 [错误 #8446]
-
sdbm 的问题将在 github.com/ruby/sdbm 上处理
-
-
已从 Ruby 标准库中删除 WEBrick。 [特性 #17303]
-
WEBrick 的问题将在 github.com/ruby/webrick 上处理
-
C API 更新¶ ↑
-
删除了与
$SAFE
相关的 C API 函数。 [特性 #16131] -
C API 头文件
ruby/ruby.h
已拆分。 [GH-2991]这对扩展库没有影响,但用户可能会遇到编译速度慢的问题。
-
内存视图接口 [实验性]
-
在“include/ruby/ractor.h”中引入了与
Ractor
相关的 C API(实验性)。
实现改进¶ ↑
-
用于
Ractor
的新方法缓存机制。 [特性 #16614]-
从 ISeq 指向的内联方法缓存可以被多个 Ractor 并行访问,即使对于方法缓存也需要同步。但是,这种同步可能会成为开销,因此引入了新的内联方法缓存机制,(1) 一次性内联方法缓存 (2) 每个类的方法缓存和 (3) 新的失效机制。(1) 可以避免每个方法调用同步,因为它仅使用原子操作。有关更多详细信息,请参阅工单。
-
-
在方法调用中使用关键字展开时分配的哈希数量已减少到最多 1 个,并且将关键字展开传递给接受特定关键字的方法不会分配哈希。
-
如果上一次调用中调用了相同类型的方法(如果不是 refinement 或属性读取器或写入器),则会优化
super
。
JIT¶ ↑
-
JIT 代码的性能改进
-
微架构优化
-
在 JIT 压缩时,由多个方法共享的本机函数会被去重。
-
通过一些优化和分割冷路径来减小程序热路径的代码大小。
-
-
实例变量
-
消除一些冗余检查。
-
在可能的情况下,在方法中跳过多次检查类和对象。
-
优化一些核心类(例如
Hash
及其子类)的访问。
-
-
某些 C 方法的
Method
内联支持-
Kernel
:#class
、#frozen?
-
Integer
:#-@
、#~
、#abs
、#bit_length
、#even?
、#integer?
、#magnitude
、#odd?
、#ord
、#to_i
、#to_int
、#zero?
-
Struct
: 用于第 10 个或之后的成员的读取方法
-
-
常量引用会被内联。
-
总是根据接收者类生成
==
、nil?
和!
调用的适当代码。 -
减少分支和方法返回时的 PC 访问次数。
-
稍微优化 C 方法调用。
-
-
编译过程改进
-
不再在 /tmp 中保留临时文件。
-
限制
GC
和 JIT 代码的压缩。 -
避免在不必要时对 JIT 代码进行 GC。
-
对 JIT 代码进行 GC 在后台线程中执行。
-
减少 Ruby 和 JIT 线程之间的锁数量。
-
静态分析¶ ↑
RBS¶ ↑
-
RBS 是一种用于定义 Ruby 程序类型的新语言。它允许编写具有高级类型的类和模块的类型,包括联合类型、重载、泛型和鸭子类型的接口类型。
-
Ruby 附带了核心/stdlib 类的类型定义。
-
rbs
gem 被捆绑用于加载和处理 RBS 文件。
TypeProf¶ ↑
-
TypeProf 是一个基于抽象解释的 Ruby 代码类型分析工具。
-
它读取未注释的 Ruby 代码,尝试推断其类型签名,并以 RBS 格式打印分析结果。
-
尽管它目前仅支持 Ruby 语言的一个子集,但我们将不断改进语言特性的覆盖率、分析性能和可用性。
-
# test.rb def foo(x) if x > 10 x.to_s else nil end end foo(42)
$ typeprof test.rb # Classes class Object def foo : (Integer) -> String? end