NEWS for Ruby 3.0.0¶ ↑
本文件列出了自 **2.7.0** 版本以来的用户可见功能变更,不包括 bug 修复。
请注意,每个条目都保持在最小限度,请查看链接以获取详细信息。
语言变更¶ ↑
-
关键字参数现在与位置参数分开。在 Ruby 2.7 中导致弃用警告的代码现在将导致
ArgumentError
或不同的行为。[功能 #14183] -
接受单个剩余参数和关键字的 Proc 不再受自动 splatting 的影响。这现在与接受单个剩余参数且没有关键字的 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
错误。[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#wait 现在可以在非阻塞上下文中调用
block
/unblock
调度程序钩子。[功能 #16786]
-
-
-
添加了
ENV.except
,它返回一个不包含给定键及其值的哈希表。[功能 #15822]
-
-
-
添加了新的编码 IBM720。[功能 #16233]
-
在 Windows 上将
Encoding.default_external
的默认值更改为 UTF-8 [功能 #16604]
-
-
-
Fiber#blocking?
用于判断纤程是否为非阻塞的。[功能 #16786] -
Fiber#backtrace
和Fiber#backtrace_locations
提供每个纤程的回溯。[功能 #16815] -
放宽了
Fiber#transfer
的限制。[错误 #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]
-
-
-
Kernel#clone
当使用freeze: false
关键字调用时,将使用freeze: false
关键字调用#initialize_clone
。[错误 #14266] -
Kernel#clone
当使用freeze: true
关键字调用时,将使用freeze: true
关键字调用#initialize_clone
,并将返回一个冻结的副本,即使接收者未冻结。[功能 #16175] -
Kernel#eval
当使用两个参数调用时,将在被评估的代码中使用"(eval)"
作为__FILE__
,使用1
作为__LINE__
。[错误 #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]
-
-
互斥锁
-
Mutex
现在是按每个Fiber
获取,而不是按每个Thread
获取。此更改应与几乎所有用法兼容,并在使用调度器时避免阻塞。[功能 #16792]
-
-
队列 / 定长队列
-
Queue#pop、SizedQueue#push 及相关方法现在可能在非阻塞上下文中调用
block
/unblock
调度器钩子。[功能 #16786]
-
-
-
添加了新类以启用并行执行。有关更多详细信息,请参阅 ractor.md。
-
-
-
以下方法现在在子类实例上调用时返回或生成
String
实例,而不是子类实例: [Bug #10845]
-
-
-
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
现在支持类别关键字参数。[功能 #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
-
向 TCPSocket.new 添加 :connect_timeout [功能 #17187]
-
-
Net::HTTP
-
Net::SMTP
-
添加 SNI 支持。
-
Net::SMTP.start 参数为关键字参数。
-
TLS 默认情况下不应检查主机名。
-
-
OpenStruct
-
初始化不再是延迟的。[Bug #12136]
-
现在可以安全地覆盖内置方法。[Bug #15409]
-
实现仅使用以
!
结尾的方法。 -
Ractor
兼容。 -
改进对 YAML 的支持。[Bug #8382]
-
官方不建议使用。请阅读 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
对象都被冻结。[Feature #8948] [Feature #16377] [Feature #15504]/foo/.frozen? #=> true (42...).frozen? # => true
-
实验性:
Hash#each
一致地生成一个包含 2 个元素的数组。[Bug #12706]-
现在
{ a: 1 }.each(&->(k, v) { })
由于 lambda 的元数检查而引发ArgumentError
。
-
-
当写入重定向到已关闭管道的 STDOUT 时,现在不会显示任何管道破损错误消息。[Feature #14413]
-
TRUE
/FALSE
/NIL
常量不再定义。 -
Integer#zero?
覆盖Numeric#zero?
以进行优化。[Misc #16961] -
Enumerable#grep
和Enumerable#grep_v
当传递一个Regexp
且没有块时,不再修改Regexp.last_match
。[Bug #17030] -
要求 'open-uri' 不再重新定义
Kernel#open
。请直接调用URI.open
或use URI#open
代替。[Misc #15893] -
由于依赖关系和性能原因,SortedSet 已被移除。
标准库兼容性问题¶ ↑
-
默认 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 标准库中移除。[Bug #8446]
-
sdbm 的问题将在 github.com/ruby/sdbm 中处理
-
-
WEBrick 已从 Ruby 标准库中移除。[Feature #17303]
-
WEBrick 的问题将在 github.com/ruby/webrick 中处理
-
C API 更新¶ ↑
-
与
$SAFE
相关的 C API 函数已被移除。[Feature #16131] -
C API 头文件
ruby/ruby.h
已被拆分。[GH-2991]这应该不会对扩展库造成影响,但用户可能会遇到编译速度慢的问题。
-
内存视图接口 [实验性]
-
内存视图接口是一组 C-API,用于在扩展库之间交换原始内存区域,例如数字数组或位图图像。扩展库还可以共享内存区域的元数据,包括形状、元素格式等。使用这些元数据,扩展库甚至可以适当地共享多维数组。此功能的设计参考了 Python 的缓冲区协议。[Feature #13767] [Feature #14722]
-
-
Ractor
相关的 C API 在“include/ruby/ractor.h”中引入(实验性)。
实现改进¶ ↑
-
为
Ractor
引入新的方法缓存机制。[Feature #16614]-
从 ISeq 指向的内联方法缓存可以被多个 Ractor 并行访问,即使对于方法缓存也需要同步。但是,这种同步可能会带来开销,因此引入了新的内联方法缓存机制,(1) 可丢弃的内联方法缓存 (2) 每个类的方法缓存和 (3) 新的失效机制。 (1) 可以避免每次方法调用时的同步,因为它只使用原子操作。有关更多详细信息,请参阅工单。
-
-
在方法调用中使用关键字 splat 时分配的哈希数量已减少到最多 1 个,并且将关键字 splat 传递给接受特定关键字的方法不会分配哈希。
-
如果
super
不是细化或 attr reader 或 writer,则在先前调用中调用相同类型的方法时会对其进行优化。
JIT¶ ↑
-
JIT 代码的性能改进
-
微体系结构优化
-
多个方法共享的本机函数在 JIT 压缩时会进行重复数据删除。
-
通过一些优化和对冷路径进行分区来减小热路径的代码大小。
-
-
实例变量
-
消除一些冗余检查。
-
在方法中尽可能跳过多次检查类和对象。
-
优化一些核心类(如
Hash
及其子类)中的访问。
-
-
Method
对某些 C 方法的内联支持-
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 附带了核心/标准库类的类型定义。
-
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
其他更改¶ ↑
-
使用
ruby2_keywords
的方法将不再保留空关键字 splat,这些关键字现在将被移除,就像不使用ruby2_keywords
的方法一样。 -
当异常在默认处理程序中被捕获时,错误消息和回溯将从最内层开始按顺序打印。[Feature #8661]
-
访问未初始化的实例变量在详细模式下不再发出警告。[Feature #17055]