新闻 for Ruby 3.1.0¶ ↑
本文档列出了自 **3.0.0** 版本以来的用户可见功能变更,不包括错误修复。
请注意,每个条目都保持在最低限度,有关详细信息,请参阅链接。
语言变更¶ ↑
-
如果块仅传递给另一个方法,则块参数现在可以是匿名的。[功能 #11256]
def foo(&) bar(&) end
-
固定运算符现在接受表达式。[功能 #17411]
Prime.each_cons(2).lazy.find_all{_1 in [n, ^(n + 2)]}.take(3).to_a #=> [[3, 5], [5, 7], [11, 13]]
-
固定运算符现在支持实例、类和全局变量。[功能 #17724]
@n = 5 Prime.each_cons(2).lazy.find{_1 in [n, ^@n]} #=> [3, 5]
-
单行模式匹配不再是实验性的。
-
在单行模式匹配中可以省略括号。[功能 #16182]
[0, 1] => _, x {y: 2} => y: x #=> 1 y #=> 2
-
多重赋值的求值顺序已与单重赋值的求值顺序保持一致。对于单重赋值,Ruby 使用从左到右的求值顺序。对于以下代码
foo[0] = bar
使用以下求值顺序
-
foo
-
bar
-
[]=
调用foo
的结果
在 3.1.0 之前的 Ruby 版本中,多重赋值不遵循此求值顺序。对于以下代码
foo[0], bar.baz = a, b
3.1.0 之前的 Ruby 版本将按以下顺序求值
-
a
-
b
-
foo
-
[]=
调用foo
的结果 -
bar
-
baz=
调用bar
的结果
从 Ruby 3.1.0 开始,求值顺序现在与单重赋值一致,左侧在右侧之前求值
-
foo
-
bar
-
a
-
b
-
[]=
调用foo
的结果 -
baz=
调用bar
的结果
[错误 #4443]
-
-
Hash
字面量和关键字参数中的值可以省略。[功能 #14579]例如,
-
{x:, y:}
是{x: x, y: y}
的语法糖。 -
foo(x:, y:)
是foo(x: x, y: y)
的语法糖。
常量名、局部变量名和方法名可以作为键名。请注意,即使是像
self
这样的伪变量名,保留字也被视为局部变量名或方法名。 -
-
非主线程可以获取类/模块的实例变量(ivars),如果 ivars 指向可共享对象。[特性 #17592]
-
在无限方法定义中允许使用命令语法,即现在可以编写
def foo = puts "Hello"
。注意private def foo = puts "Hello"
无法解析。[特性 #17398]
命令行选项¶ ↑
-
--disable-gems
现在明确声明为“仅供调试”。在任何实际代码库中都不要使用它。[特性 #17684]
核心类更新¶ ↑
注意:我们只列出未完成的类更新。
-
-
Array#intersect?
已添加。[特性 #15198]
-
-
-
Class#subclasses
,它返回直接继承自接收者的类数组,不包括单例类。[特性 #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
已添加。[特性 #17312] -
Enumerable#tally
现在接受一个可选的哈希表进行计数。[特性 #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
现在接受一个可选参数,用于指定要剥离路径组件的级别。[特性 #12194]
-
-
-
"GC.measure_total_time = true" 启用
GC
的测量。测量可能会引入开销。默认情况下启用。GC.measure_total_time
返回当前设置。GC.stat[:time]
或GC.stat
(:time) 返回以毫秒为单位的测量时间。[[特性 #10917]] -
GC.total_time
返回以纳秒为单位的测量时间。[[功能 #10917]]
-
-
-
Integer.try_convert
已添加。[功能 #15211]
-
-
-
Kernel#load
现在接受模块作为第二个参数,并将使用给定模块作为顶层模块加载文件。[功能 #6210]
-
-
-
Marshal.load
现在接受freeze: true
选项。所有返回的对象都被冻结,除了Class
和Module
实例。字符串被去重。[功能 #18148]
-
-
-
MatchData#match
已添加 [功能 #18172]
-
-
-
Method#public?, Method#private?, Method#protected?, UnboundMethod#public?, UnboundMethod#private?, UnboundMethod#protected? 已添加。[功能 #11689]
-
-
-
Module#prepend
现在如果接收者已经包含了参数,就会修改祖先链。Module#prepend
仍然不会修改祖先链,如果接收者已经预先添加了参数。[错误 #17423] -
Module#private
、public、protected 和 module_function 现在将返回它们的 arguments。如果给出了单个参数,则返回它。如果没有给出参数,则返回 nil。如果给出了多个参数,则将它们作为数组返回。[功能 #12495]
-
-
-
Process
._fork 已添加。这是 fork(2) 的核心方法。不要直接调用此方法;它由现有的 fork 方法调用:Kernel
.#fork、Process.fork
和IO.popen
(“-”)。应用程序监控库可以覆盖此方法来挂钩 fork 事件。[功能 #17795]
-
-
-
将 Unicode 版本更新至 13.0.0 [功能 #17750],并将 Emoji 版本更新至 13.0 [功能 #18029]
-
String#unpack
和String#unpack1
现在接受offset:
关键字参数,以便在跳过任意数量的字节后开始解包。如果offset
超出字符串边界,则会引发ArgumentError
。[功能 #18254]
-
-
-
添加了
Thread::Backtrace.limit
,它返回由--backtrace-limit
命令行选项设置的限制回溯长度的值。[功能 #17479]
-
-
-
Thread::Queue.new
现在接受Enumerable
的初始值。[功能 #17327]
-
-
-
Time.new
现在接受可选的in:
关键字参数用于时区,以及Time.at
和Time.now
,因此现在您可以省略Time.new
的次要参数。[功能 #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
。[功能 #17544]
-
-
-
添加了
TracePoint.allow_reentry
以允许在TracePoint
回调期间重新进入。[功能 #15912]
-
-
$LOAD_PATH
-
$LOAD_PATH.resolve_feature_path 不会引发异常。[功能 #16043]
-
-
Fiber
调度程序-
添加了对使用
address_resolve
钩子的Addrinfo.getaddrinfo
的支持。[功能 #17370] -
使用
timeout_after
钩子引入了非阻塞Timeout.timeout
。[功能 #17470] -
引入了新的调度程序钩子
io_read
和io_write
以及用于零拷贝读/写的低级IO::Buffer
。[功能 #18020] -
使
Monitor
成为线程安全的。[Bug #17827] -
用 pthread 实现替换复制协程。[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.suspend
暂时停止测量,并使用Coverage.resume
重新启动它。详细了解 [Feature #18176]。 -
Random::Formatter
已移至 random/formatter.rb,因此您可以使用Random#hex
、Random#base64
等,而无需 SecureRandom。[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
即使没有 -w 也会警告safe_level
和后面的参数。[Feature #14256] -
lib/debug.rb
被debug.gem
替换。 -
lib/pp.rb
中的Kernel#pp
默认使用IO#winsize
的宽度。这意味着输出宽度会根据您的终端大小自动改变。[Feature #12913] -
Psych 4.0 默认将
Psych.load
更改为safe_load
。您可能需要使用 Psych 3.3.2 来迁移到此行为。[Bug #17866]
C API 更新¶ ↑
-
已记录。[GH-4815]
-
rb_gc_force_recycle
已被弃用,并已更改为无操作。[Feature #18290]
实现改进¶ ↑
-
引入了用于读取类变量的内联缓存机制。[Feature #17763]
-
instance_eval
和instance_exec
现在仅在需要时才分配单例类,避免了额外的对象并提高了性能。[GH-5146] -
Struct
访问器的性能得到提升。[GH-5131] -
mandatory_only?
内置特殊形式,用于提高内置方法的性能。[GH-5112] -
垃圾收集器中的实验性功能可变宽度分配。此功能默认情况下处于关闭状态,可以通过使用标志
USE_RVARGC=1
编译 Ruby 来启用。[Feature #18045] [Feature #18239]
JIT¶ ↑
-
将 Ruby 3.0 的
--jit
重命名为--mjit
,并将--jit
作为别名用于非 Windows x86-64 平台上的--yjit
,以及其他平台上的--mjit
。
MJIT¶ ↑
-
默认的
--mjit-max-cache
已从 100 更改为 10000。 -
当启用针对类事件的
TracePoint
时,JIT 代码不再被取消。 -
JIT 编译器不再跳过编译长度超过 1000 条指令的方法。
-
当由于使用
TracePoint
或GC.compact
而禁用 JIT 代码时,--mjit-verbose
和--mjit-warning
输出“JIT 取消”。
YJIT:新的实验性进程内 JIT 编译器¶ ↑
新的 JIT 编译器作为实验性功能提供。[功能 #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
,您就可以调查对象是在哪里创建的。请注意,仅包含此文件会带来很大的性能开销。这仅用于调试目的。不要在生产环境中使用它。[功能 #17762] -
现在,除非
$VERBOSE
为nil
,否则在终结器中引发的异常将被打印到STDERR
。[功能 #17798] -
ruby -run -e httpd
显示访问的 URL。[功能 #17847] -
添加
ruby -run -e colorize
以使用IRB::Color.colorize_code
对 Ruby 代码进行着色。