NEWS for Ruby 3.1.0
本文档列出了自 3.0.0 版本以来用户可见的功能性更改,但不包括错误修复。
请注意,每个条目都保持得尽可能简洁,详情请参阅链接。
语言更改
-
如果代码块只传递给另一个方法,则代码块参数现在可以是匿名的。 [Feature #11256]
def foo(&) bar(&) end
-
Pin 操作符现在接受表达式。 [Feature #17411]
Prime.each_cons(2).lazy.find_all{_1 in [n, ^(n + 2)]}.take(3).to_a #=> [[3, 5], [5, 7], [11, 13]]
-
Pin 操作符现在支持实例变量、类变量和全局变量。 [Feature #17724]
@n = 5 Prime.each_cons(2).lazy.find{_1 in [n, ^@n]} #=> [3, 5]
-
单行模式匹配不再是实验性的。
-
单行模式匹配中可以省略括号。 [Feature #16182]
[0, 1] => _, x {y: 2} => y: x #=> 1 y #=> 2
-
多个赋值的求值顺序已与单个赋值的求值顺序保持一致。在单个赋值中,Ruby 使用从左到右的求值顺序。对于此代码:
foo[0] = bar
以下求值顺序将被使用:
-
foo -
bar -
对 `foo` 的结果调用 `[]=
在 Ruby 3.1.0 之前的版本中,多个赋值不遵循此求值顺序。对于此代码:
foo[0], bar.baz = a, b
Ruby 3.1.0 之前的版本将按以下顺序进行求值:
-
a -
b -
foo -
对 `foo` 的结果调用 `[]=
-
bar -
对 `bar` 的结果调用 `baz=
从 Ruby 3.1.0 开始,求值顺序现已与单个赋值保持一致,左侧表达式在右侧表达式之前进行求值。
-
foo -
bar -
a -
b -
对 `foo` 的结果调用 `[]=
-
对 `bar` 的结果调用 `baz=
-
-
可以省略 `Hash` 字面量和关键字参数中的值。 [Feature #14579]
例如,
-
{x:, y:}是{x: x, y: y}的语法糖。 -
foo(x:, y:)是foo(x: x, y: y)的语法糖。
允许使用常量名、局部变量名和方法名作为键名。请注意,即使是伪变量名(如
self),保留字也被视为局部变量或方法名。 -
-
非主 Ractor 可以获取类/模块的实例变量(ivars),如果 ivars 指向可共享对象。 [Feature #17592]
-
在无尽方法定义中允许使用命令语法,即现在可以编写
def foo = puts "Hello"。请注意,private def foo = puts "Hello"不会被解析。 [Feature #17398]
命令行选项
-
--disable-gems现在被明确声明为“仅用于调试”。切勿在任何实际代码库中使用它。 [Feature #17684]
核心类更新
注意:此处仅列出重要的类更新。
-
-
Array#intersect?已添加。 [Feature #15198]
-
-
Class
-
Class#subclasses,它返回直接继承自接收者的类的数组,不包括单例类。 [Feature #18273]class A; end class B < A; end class C < B; end class D < A; end A.subclasses #=> [D, B] B.subclasses #=> [C] C.subclasses #=> []
-
-
-
Enumerable#compact已添加。 [Feature #17312] -
Enumerable#tally现在接受一个可选的哈希进行计数。 [Feature #17744] -
Enumerable#each_cons和 each_slice 现在返回接收者。 [GH-1509][1, 2, 3].each_cons(2){} # 3.0 => nil # 3.1 => [1, 2, 3] [1, 2, 3].each_slice(2){} # 3.0 => nil # 3.1 => [1, 2, 3]
-
-
-
File.dirname现在接受一个可选参数,用于指定要剥离的路径组件级别。 [Feature #12194]
-
-
-
"GC.measure_total_time = true" 启用对
GC的测量。测量可能会引入开销。此选项默认启用。GC.measure_total_time返回当前设置。GC.stat[:time]或GC.stat(:time) 返回以毫秒为单位的测量时间。 [[Feature #10917]] -
GC.total_time返回以纳秒为单位的测量时间。 [[Feature #10917]]
-
-
-
Kernel#load现在接受一个模块作为第二个参数,并将使用给定模块作为顶级模块来加载文件。 [Feature #6210]
-
-
-
Marshal.load现在接受一个freeze: true选项。除Class和Module实例外,所有返回的对象都会被冻结。字符串会被去重。 [Feature #18148]
-
-
-
MatchData#match已添加。 [Feature #18172]
-
-
方法 /
UnboundMethod-
已添加 Method#public?, Method#private?, Method#protected?, UnboundMethod#public?, UnboundMethod#private?, UnboundMethod#protected?。 [Feature #11689]
-
-
Module
-
Module#prepend现在会在接收者已包含参数时修改祖先链。如果接收者已预先包含该参数,Module#prepend仍不会修改祖先链。 [Bug #17423] -
Module#private、public、protected 和 module_function 现在将返回其参数。如果给出单个参数,则返回该参数。如果未给出参数,则返回 nil。如果给出多个参数,则以数组形式返回。 [Feature #12495]
-
-
Process
-
Process._fork已添加。这是 fork(2) 的核心方法。请勿直接调用此方法;现有 fork 方法会调用它:Kernel.#fork、Process.fork和IO.popen(“-”)。应用程序监控库可以覆盖此方法以挂钩 fork 事件。 [Feature #17795]
-
-
-
向 Struct#initialize 仅传递关键字参数会发出警告。您需要使用
Hash字面量将Hash设置为第一个成员。 [Feature #16806]
-
-
-
Unicode 版本更新至 13.0.0 [Feature #17750],Emoji 版本更新至 13.0 [Feature #18029]
-
String#unpack和String#unpack1现在接受offset:关键字参数,以在跳过任意数量字节后开始解包。如果offset超出字符串边界,将引发ArgumentError。 [Feature #18254]
-
-
-
已添加
Thread::Backtrace.limit,它返回由--backtrace-limit命令行选项设置的用于限制回溯长度的值。 [Feature #17479]
-
-
-
Thread::Queue.new现在接受一个包含初始值的Enumerable。 [Feature #17327]
-
-
-
Time.new现在接受可选的in:关键字参数用于时区,Time.at和Time.now也是如此,因此您现在可以省略Time.new的次要参数。 [Feature #17485]Time.new(2021, 12, 25, in: "+07:00") #=> 2021-12-25 00:00:00 +0700
与此同时,时间组件字符串现在被更严格地转换为整数。
Time.new(2021, 12, 25, "+07:30") #=> invalid value for Integer(): "+07:30" (ArgumentError)
Ruby 3.0 或更早版本可能返回意外结果
2021-12-25 07:00:00,而不是2021-12-25 07:30:00或2021-12-25 00:00:00 +07:30。 -
Time#strftime支持 RFC 3339 UTC 的未知偏移本地时间(-0000),作为%-z。 [Feature #17544]
-
-
-
已添加
TracePoint.allow_reentry以允许在TracePoint回调期间重新进入。 [Feature #15912]
-
-
$LOAD_PATH
-
$LOAD_PATH.resolve_feature_path 不再引发错误。 [Feature #16043]
-
-
Fiber调度器-
使用
address_resolve钩子添加了对Addrinfo.getaddrinfo的支持。 [Feature #17370] -
使用
timeout_after钩子引入了非阻塞Timeout.timeout。 [Feature #17470] -
引入了新的调度器钩子
io_read和io_write,以及用于零拷贝读/写的低级IO::Buffer。 [Feature #18020] -
IO钩子io_wait、io_read、io_write在可能的情况下接收原始IO对象。 [Bug #18003] -
使
Monitor成为纤程安全。 [Bug #17827] -
用 pthread 实现替换了 copy coroutine。 [Feature #18015]
-
-
-
表示由
Module#refine创建的模块的新类。`include` 和 `prepend` 已被弃用,取而代之的是import_methods。 [Bug #17429]
-
标准库更新
-
以下默认 gem 已更新。
-
RubyGems 3.3.3
-
base64 0.1.1
-
benchmark 0.2.0
-
bigdecimal 3.1.1
-
bundler 2.3.3
-
cgi 0.3.1
-
csv 3.2.2
-
date 3.2.2
-
did_you_mean 1.6.1
-
digest 3.1.0
-
drb 2.1.0
-
erb 2.2.3
-
error_highlight 0.3.0
-
etc 1.3.0
-
fcntl 1.0.1
-
fiddle 1.1.0
-
fileutils 1.6.0
-
find 0.1.1
-
io-console 0.5.10
-
io-wait 0.2.1
-
ipaddr 1.2.3
-
irb 1.4.1
-
json 2.6.1
-
logger 1.5.0
-
net-http 0.2.0
-
net-protocol 0.1.2
-
nkf 0.1.1
-
open-uri 0.2.0
-
openssl 3.0.0
-
optparse 0.2.0
-
ostruct 0.5.2
-
pathname 0.2.0
-
pp 0.3.0
-
prettyprint 0.1.1
-
psych 4.0.3
-
racc 1.6.0
-
rdoc 6.4.0
-
readline 0.0.3
-
readline-ext 0.1.4
-
reline 0.3.0
-
resolv 0.2.1
-
rinda 0.1.1
-
ruby2_keywords 0.0.5
-
securerandom 0.1.1
-
set 1.0.2
-
stringio 3.0.1
-
strscan 3.0.1
-
tempfile 0.1.2
-
time 0.2.0
-
timeout 0.2.0
-
tmpdir 0.1.2
-
un 0.2.0
-
uri 0.11.0
-
yaml 0.2.0
-
zlib 2.1.1
-
RubyGems 3.3.3
-
base64 0.1.1
-
benchmark 0.2.0
-
bigdecimal 3.1.1
-
bundler 2.3.3
-
cgi 0.3.1
-
csv 3.2.2
-
date 3.2.2
-
did_you_mean 1.6.1
-
digest 3.1.0
-
drb 2.1.0
-
erb 2.2.3
-
error_highlight 0.3.0
-
etc 1.3.0
-
fcntl 1.0.1
-
fiddle 1.1.0
-
fileutils 1.6.0
-
find 0.1.1
-
io-console 0.5.10
-
io-wait 0.2.1
-
ipaddr 1.2.3
-
irb 1.4.1
-
json 2.6.1
-
logger 1.5.0
-
net-http 0.2.0
-
net-protocol 0.1.2
-
nkf 0.1.1
-
open-uri 0.2.0
-
openssl 3.0.0
-
optparse 0.2.0
-
ostruct 0.5.2
-
pathname 0.2.0
-
pp 0.3.0
-
prettyprint 0.1.1
-
psych 4.0.3
-
racc 1.6.0
-
rdoc 6.4.0
-
readline 0.0.3
-
readline-ext 0.1.4
-
reline 0.3.0
-
resolv 0.2.1
-
rinda 0.1.1
-
ruby2_keywords 0.0.5
-
securerandom 0.1.1
-
set 1.0.2
-
stringio 3.0.1
-
strscan 3.0.1
-
tempfile 0.1.2
-
time 0.2.0
-
timeout 0.2.0
-
tmpdir 0.1.2
-
un 0.2.0
-
uri 0.11.0
-
yaml 0.2.0
-
zlib 2.1.1
-
-
以下捆绑 gem 已更新。
-
minitest 5.15.0
-
power_assert 2.0.1
-
rake 13.0.6
-
test-unit 3.5.3
-
rexml 3.2.5
-
rbs 2.0.0
-
typeprof 0.21.1
-
minitest 5.15.0
-
power_assert 2.0.1
-
rake 13.0.6
-
test-unit 3.5.3
-
rexml 3.2.5
-
rbs 2.0.0
-
typeprof 0.21.1
-
-
以下默认 gem 现在是捆绑 gem。
-
net-ftp 0.1.3
-
net-imap 0.2.2
-
net-pop 0.1.1
-
net-smtp 0.3.1
-
matrix 0.4.2
-
prime 0.1.2
-
debug 1.4.0
-
net-ftp 0.1.3
-
net-imap 0.2.2
-
net-pop 0.1.1
-
net-smtp 0.3.1
-
matrix 0.4.2
-
prime 0.1.2
-
debug 1.4.0
-
-
以下 gem 已从 Ruby 标准库中移除。
-
dbm
-
gdbm
-
tracer
-
dbm
-
gdbm
-
tracer
-
-
Coverage测量现在支持暂停。您可以使用Coverage.suspend暂时停止测量,并使用Coverage.resume重新启动。有关详细信息,请参阅 [Feature #18176]。 -
Random::Formatter已移动到 random/formatter.rb,以便您可以在不使用SecureRandom的情况下使用Random#hex、Random#base64等。 [Feature #18190]
兼容性问题
注意:不包括功能性错误修复。
-
rb_io_wait_readable、rb_io_wait_writable和rb_wait_for_single_fd已被弃用,分别替换为rb_io_maybe_wait_readable、rb_io_maybe_wait_writable和rb_io_maybe_wait。rb_thread_wait_fd和rb_thread_fd_writable已被弃用。 [Bug #18003]
标准库兼容性问题
-
ERB#initialize会警告safe_level及后续参数,即使没有 -w 选项。 [Feature #14256] -
lib/debug.rb已被debug.gem替换。 -
Kernel#pp在 lib/pp.rb 中默认使用IO#winsize的宽度。这意味着输出宽度会根据您的终端大小自动更改。 [Feature #12913] -
Psych4.0 将Psych.load默认更改为safe_load。您可能需要使用Psych3.3.2 来迁移到此行为。 [Bug #17866]
C API 更新
-
已文档化。 [GH-4815]
-
rb_gc_force_recycle已被弃用,并已更改为无操作。 [Feature #18290]
实现改进
-
引入了内联缓存机制来读取类变量。 [Feature #17763]
-
instance_eval和instance_exec现在仅在需要时才分配单例类,避免了额外的对象并提高了性能。 [GH-5146] -
mandatory_only?内置特殊形式,以提高内置方法的性能。 [GH-5112] -
垃圾收集器中的实验性功能:可变宽度分配。此功能默认关闭,可以通过使用标志
USE_RVARGC=1进行编译来启用。 [Feature #18045] [Feature #18239]
JIT
-
将 Ruby 3.0 的
--jit重命名为--mjit,并在非 Windows x86-64 平台上将--jit别名化为--yjit,在其他平台上别名化为--mjit。
MJIT
-
默认的
--mjit-max-cache已从 100 更改为 10000。 -
当启用类事件的
TracePoint时,JIT 生成的代码不再被取消。 -
JIT 编译器不再跳过长度超过 1000 条指令的方法的编译。
-
--mjit-verbose和--mjit-warning在 JIT 生成的代码因使用TracePoint或 GC.compact 而被禁用时,输出“JIT cancel”。
YJIT:新的实验性进程内 JIT 编译器
新的 JIT 编译器作为实验性功能可用。 [Feature #18229]
请参阅介绍该项目的这篇博客文章。
-
默认禁用,使用
--yjit命令行选项启用 YJIT。 -
在基于真实世界软件的基准测试中性能有所提高,railsbench 提高 22%,liquid-render 提高 39%。
-
快速预热时间。
-
目前仅限于类 Unix 的 x86-64 平台。
静态分析
RBS
-
泛型类型参数可以被约束(PR)。
# `T` must be compatible with the `_Output` interface. # `PrettyPrint[String]` is ok, but `PrettyPrint[Integer]` is a type error. class PrettyPrint[T < _Output] interface _Output def <<: (String) -> void end attr_reader output: T def initialize: (T output) -> void end -
类型别名可以为泛型。(PR)
# Defines a generic type `list`. type list[T] = [ T, list[T] ] | nil type str_list = list[String] type int_list = list[Integer] -
引入了 rbs collection 来管理 gem 的 RBS。
-
已添加/更新了许多内置库和标准库的签名。
-
它还包括许多错误修复和性能改进。
有关更多信息,请参阅 CHANGELOG.md。
TypeProf
-
已实现实验性 IDE 支持。
-
自 Ruby 3.0.0 以来,许多错误修复和性能改进。
调试器
-
捆绑了一个新的调试器 debug.gem。debug.gem 是一个快速的调试器实现,它提供了许多功能,如远程调试、彩色 REPL、IDE(VSCode)集成等。它取代了
lib/debug.rb标准库。 -
rdbg命令也安装在bin/目录中,用于启动和控制调试执行。
error_highlight
引入了一个名为 error_highlight 的内置 gem。它在回溯中显示精细化的错误位置。
示例:title = json[:article][:title]
如果 json 为 nil,它将显示:
$ ruby test.rb
test.rb:2:in `<main>': undefined method `[]' for nil:NilClass (NoMethodError)
title = json[:article][:title]
^^^^^^^^^^
如果 json[:article] 返回 nil,它将显示:
$ ruby test.rb
test.rb:2:in `<main>': undefined method `[]' for nil:NilClass (NoMethodError)
title = json[:article][:title]
^^^^^^^^
此功能默认启用。您可以使用命令行选项 --disable-error_highlight 禁用它。有关详细信息,请参阅 存储库。
IRB 自动完成和文档显示
IRB 现在具有自动完成功能,您只需键入代码,就会出现候选词列表。您可以使用 Tab 和 Shift+Tab 键向上或向下滚动。
如果安装了文档,当您选择一个候选词时,文档对话框将出现在候选词对话框旁边,显示部分内容。您可以通过按 Alt+d 来阅读完整文档。
杂项更改
-
添加了
lib/objspace/trace.rb,这是一个用于跟踪对象分配的工具。只需包含此文件,跟踪就会*立即*开始。只需通过Kernel#p,您就可以调查对象是在哪里创建的。请注意,仅仅包含此文件会带来很大的性能开销。这仅用于调试目的。请勿在生产环境中使用。 [Feature #17762] -
现在,最终化器中引发的异常将打印到
STDERR,除非$VERBOSE为nil。 [Feature #17798] -
ruby -run -e httpd会显示可访问的 URL。 [Feature #17847] -
添加
ruby -run -e colorize以使用IRB::Color.colorize_code为 Ruby 代码着色。