Ruby 3.0.0 的 NEWS ¶ ↑
本文档列出了自 2.7.0 版本以来,用户可见的功能变更,不包括错误修复。
请注意,每个条目都尽量保持简洁,详情请参阅链接。
语言变更¶ ↑
-
关键字参数现在与位置参数分离。在 Ruby 2.7 中导致弃用警告的代码,现在将导致
ArgumentError
或不同的行为。[特性 #14183] -
接受单个剩余参数和关键字的 Proc 不再受自动展开的影响。这现在与接受单个剩余参数且不带关键字的 Proc 的行为相匹配。[特性 #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}]], {}]
-
参数转发 (
...
) 现在支持前导参数。[特性 #16378]def method_missing(meth, ...) send(:"do_#{meth}", ...) end
-
模式匹配 (
case/in
) 不再是实验性的。[特性 #17260] -
单行模式匹配已重新设计。[实验性]
-
添加了查找模式。[实验性] [特性 #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
-
添加了无尽方法定义。[实验性] [特性 #16746]
def square(x) = x * x
-
当使用
# frozen-string-literal: true
时,内插的String
字面量不再冻结。[特性 #17104] -
添加了魔法注释
shareable_constant_value
来冻结常量。有关详细信息,请参阅魔法注释。[特性 #17273] -
引入了 静态分析 基础。
-
默认情况下不再显示弃用警告(自 Ruby 2.7.2 起)。使用
-W:deprecated
启用它们(或使用-w
也显示其他警告)。[特性 #16345] -
$SAFE
和$KCODE
现在是正常的全局变量,没有特殊的行为。与$SAFE
相关的 C-API 方法已被删除。[特性 #16131] [特性 #17136] -
方法中单例类定义中的 yield 现在是一个
SyntaxError
,而不是警告。方法外部的类定义中的 yield 现在是一个SyntaxError
,而不是LocalJumpError
。[特性 #15575] -
当类变量被祖先类/模块中的相同定义覆盖时,现在会引发
RuntimeError
(以前,它仅在详细模式下发出警告)。此外,从顶层作用域访问类变量现在是RuntimeError
。[Bug #14541] -
赋值给编号的参数现在是
SyntaxError
,而不是警告。
命令行选项¶ ↑
--help
选项¶ ↑
当环境变量 RUBY_PAGER
或 PAGER
存在且具有非空值,并且标准输入和输出是 tty 时,--help
选项通过该值指定的寻呼机显示帮助消息。[特性 #16754]
--backtrace-limit
选项¶ ↑
--backtrace-limit
选项限制回溯的最大长度。[特性 #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
调度程序钩子。[特性 #16786]
-
-
-
添加了
ENV.except
,它返回一个不包含给定键及其值的哈希。[特性 #15822]
-
-
-
添加了新的编码 IBM720。[特性 #16233]
-
将
Encoding.default_external
在 Windows 上的默认值更改为 UTF-8 [特性 #16604]
-
-
-
Fiber#blocking?
告诉光纤是否是非阻塞的。[特性 #16786] -
Fiber#backtrace
和Fiber#backtrace_locations
提供每个光纤的回溯。[特性 #16815] -
放宽了
Fiber#transfer
的限制。[Bug #17221]
-
-
添加了 GC.auto_compact= 和 GC.auto_compact 来控制何时运行压缩。将
auto_compact=
设置为true
将导致压缩在主要回收期间发生。目前,压缩会给主要回收增加显著的开销,所以请先进行测试! [特性 #17176]
-
-
-
Hash#transform_keys
和Hash#transform_keys!
现在接受一个将键映射到新键的哈希。[特性 #16274] -
添加了
Hash#except
,它返回一个不包含给定键及其值的哈希。[特性 #15822]
-
-
-
IO#nonblock?
现在默认为true
。[特性 #16786] -
IO#wait_readable
、IO#wait_writable
、IO#read
、IO#write
和其他相关方法(例如IO#puts
、IO#gets
)可以在非阻塞执行上下文中调用调度程序钩子 io_wait(io, events, timeout)。[特性 #16786]
-
-
-
当使用
freeze: false
关键字调用时,Kernel#clone
将使用freeze: false
关键字调用 initialize_clone。[Bug #14266] -
当使用
freeze: true
关键字调用时,Kernel#clone
将使用freeze: true
关键字调用 initialize_clone,即使接收者未冻结,也将返回冻结的副本。[特性 #16175] -
当使用两个参数调用时,
Kernel#eval
将在求值代码中使用"(eval)"
作为__FILE__
,使用1
作为__LINE__
。[Bug #4352] -
如果调用时没有字面块,
Kernel#lambda
现在会发出警告。[特性 #15973] -
Kernel.sleep
在非阻塞执行上下文中调用调度程序钩子 kernel_sleep(…)。[特性 #16786]
-
-
-
Module#include
和Module#prepend
现在会影响已经包含或预置接收者的类和模块,镜像了如果参数在其他模块和类包含或预置接收者之前包含在接收者中的行为。[特性 #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”方法现在接受包含方法名称列表的单个数组参数。[特性 #17314] -
Module#attr_accessor
,Module#attr_reader
,Module#attr_writer
和Module#attr
方法现在返回定义的方法名称数组(以符号表示)。[特性 #17314] -
Module#alias_method
现在返回定义的别名(以符号表示)。[特性 #17314]
-
-
互斥锁
-
Queue / SizedQueue
-
Queue#pop、SizedQueue#push 和相关方法现在可以在非阻塞上下文中调用
block
/unblock
调度器钩子。[特性 #16786]
-
-
-
添加了新类以启用并行执行。有关更多详细信息,请参见 ractor.md。
-
-
-
Random::DEFAULT
现在指的是Random
类,而不是Random
实例,因此它可以与Ractor
一起使用。[特性 #17322] -
Random::DEFAULT
已被弃用,因为它现在的值令人困惑,并且不再是全局的,请直接使用Kernel.rand
/Random.rand
,或者使用Random.new
创建Random
实例。[特性 #17351]
-
-
-
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]
-
Stdlib 更新¶ ↑
仅限突出的更新。
-
-
更新至
BigDecimal
3.0.0 -
此版本与
Ractor
兼容。
-
-
-
更新至
Bundler
2.2.3
-
-
-
更新至 0.2.0
-
此版本与
Ractor
兼容。
-
-
CSV
-
更新至 CSV 3.1.9
-
-
-
更新至
Fiddle
1.0.5
-
-
IRB
-
更新至 IRB 1.2.6
-
-
-
将 :connect_timeout 添加到
TCPSocket.new
。[特性 #17187]
-
-
-
添加了
Net::HTTP#verify_hostname=
和Net::HTTP#verify_hostname
来跳过主机名验证。[特性 #16555] -
当第一个参数是
URI
时,Net::HTTP.get
,Net::HTTP.get_response
和Net::HTTP.get_print
可以将请求标头作为Hash
在第二个参数中。[特性 #16686]
-
-
Net::SMTP
-
添加 SNI 支持。
-
Net::SMTP.start 参数是关键字参数。
-
TLS 默认情况下不应检查主机名。
-
-
-
与
Ractor
兼容。
-
-
-
更新至
Reline
0.1.5
-
-
RubyGems
-
更新至 RubyGems 3.2.3
-
-
-
更新至
StringScanner
3.0.0 -
此版本与
Ractor
兼容。
-
-
-
已删除 URI.escape 和 URI.unescape。请根据您的具体用例改用以下方法。
-
兼容性问题¶ ↑
不包括特性缺陷修复。
-
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。
Stdlib 兼容性问题¶ ↑
-
默认 gem
-
以下库从 stdlib 升级为默认 gem。
-
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
-
以下扩展从 stdlib 升级为默认 gem。
-
digest
-
io-nonblock
-
io-wait
-
nkf
-
pathname
-
syslog
-
win32ole
-
-
-
捆绑的 gem
-
net-telnet 和 xmlrpc 已从捆绑的 gem 中删除。如果您有兴趣维护它们,请在 github.com/ruby/xmlrpc 或 github.com/ruby/net-telnet 上评论您的计划。
-
-
SDBM 已从 Ruby 标准库中删除。[缺陷 #8446]
-
sdbm 的问题将在 github.com/ruby/sdbm 上处理。
-
-
WEBrick 已从 Ruby 标准库中移除。 [特性 #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) 可以避免每个方法调用的同步,因为它只使用原子操作。有关更多详细信息,请参阅工单。
-
-
在使用方法调用中的关键字 splat 时,分配的哈希数量已减少到最多 1 个,并且将关键字 splat 传递给接受特定关键字的方法不会分配哈希。
-
如果前一次调用中调用的是相同类型的方法,并且不是 refinements 或 attr 读取器或写入器,则
super
会被优化。
JIT¶ ↑
-
JIT 编译代码的性能改进
-
编译过程改进
-
不再将临时文件保存在 /tmp 中。
-
限制
GC
和 JIT 编译代码的压缩。 -
避免在不需要时 GC JIT 编译的代码。
-
GC JIT 编译的代码在后台线程中执行。
-
减少 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