新闻 for Ruby 3.3.0¶ ↑
本文档列出了自 **3.2.0** 版本以来的用户可见功能更改,但不包括错误修复。
请注意,每个条目都保持在最小限度,有关详细信息,请参阅链接。
命令行选项¶ ↑
-
引入了一个新的
performance
警告类别。即使在详细模式下,它们默认也不会显示。使用-W:performance
或Warning[:performance] = true
启用它们。[功能 #19538] -
引入了一个新的
RUBY_CRASH_REPORT
环境变量,允许将 Ruby 崩溃报告重定向到文件或子命令。有关更多详细信息,请参阅 ruby 手册页的BUG REPORT ENVIRONMENT
部分。[功能 #19790]
核心类更新¶ ↑
注意:我们只列出突出的类更新。
-
-
Array#pack
现在为未知指令引发ArgumentError
。[错误 #19150]
-
-
-
Dir.for_fd
添加用于返回由提供的目录文件描述符指定的目录的Dir
对象。[功能 #19347] -
Dir.fchdir
添加用于将目录更改为由提供的目录文件描述符指定的目录。[功能 #19347]
-
-
-
Encoding#replicate
已被删除,它已经过时。[功能 #18949]
-
-
-
引入
Fiber#kill
。[错误 #595]fiber = Fiber.new do while true puts "Yielding..." Fiber.yield end ensure puts "Exiting..." end fiber.resume # Yielding... fiber.kill # Exiting...
-
-
-
MatchData#named_captures
现在接受可选的symbolize_names
关键字。[功能 #19591]
-
-
-
Module#set_temporary_name
添加用于为模块设置临时名称。[功能 #19521]
-
-
-
新的核心类用于构建具有弱引用的集合。该类使用等价语义来查找键,就像一个普通的哈希表一样,但它不会对键保持强引用。[功能 #18498]
-
-
-
ObjectSpace::WeakMap#delete
已被添加以积极清除弱映射条目。[功能 #19561]
-
-
-
现在
Proc#dup
和Proc#clone
分别调用#initialize_dup
和#initialize_clone
钩子。[功能 #19362]
-
-
-
新的
Process.warmup
方法通知 Ruby 虚拟机启动序列已完成,现在是优化应用程序的最佳时机。这对于长时间运行的应用程序很有用。执行的实际优化完全是特定于实现的,并且将来可能会在未经通知的情况下更改。[功能 #18885]
-
-
-
Process::Status#&
和Process::Status#>>
已被弃用。[错误 #19868]
-
-
-
Range#reverse_each
现在可以处理具有Integer
终点的无起始范围。[功能 #18515] -
Range#reverse_each
现在为无穷范围引发TypeError
。[功能 #18551] -
Range#overlap?
已被添加用于检查两个范围是否重叠。[功能 #19839]
-
-
-
添加
Refinement#target
作为Refinement#refined_class
的替代方案。Refinement#refined_class
已被弃用,将在 Ruby 3.4 中删除。[功能 #19714]
-
-
-
String#unpack
现在为未知指令引发ArgumentError
。[错误 #19150] -
String#bytesplice
现在接受新的参数 index/length 或要复制的源字符串的范围。[功能 #19314]
-
-
-
Time.new
使用字符串参数变得更加严格。[Bug #19293]Time.new('2023-12-20') # no time information (ArgumentError)
-
-
-
TracePoint
支持rescue
事件。当抛出的异常被捕获时,TracePoint
会触发钩子。rescue
事件只支持 Ruby 层级的rescue
。[Feature #19572]
-
标准库更新¶ ↑
-
RubyGems 和
Bundler
会在用户未将以下 gem 添加到 Gemfile 或 gemspec 中就使用require
时发出警告。这是因为它们将在未来版本的 Ruby 中成为捆绑的 gem。如果您使用 bootsnap gem,此警告将被抑制。我们建议您至少使用一次DISABLE_BOOTSNAP=1
环境变量运行您的应用程序。这是此版本的限制。[Feature #19351] [Feature #19776] [Feature #19843]-
abbrev
-
base64
-
bigdecimal
-
csv
-
drb
-
getoptlong
-
mutex_m
-
nkf
-
observer
-
racc
-
resolv-replace
-
rinda
-
syslog
-
abbrev
-
base64
-
bigdecimal
-
csv
-
drb
-
getoptlong
-
mutex_m
-
nkf
-
observer
-
racc
-
resolv-replace
-
rinda
-
syslog
-
-
Socket#recv
和Socket#recv_nonblock
在关闭连接时返回nil
而不是空字符串。Socket#recvmsg
和Socket#recvmsg_nonblock
在关闭连接时返回nil
而不是空数据包。[Bug #19012] -
现在可以中断诸如
Socket.getaddrinfo
、Socket.getnameinfo
、Addrinfo.getaddrinfo
等的名称解析。[Feature #19965] -
Random::Formatter#alphanumeric
扩展为接受可选的chars
关键字参数。[功能 #18183]
添加了以下默认 gem。
-
prism 0.19.0
以下默认 gem 已更新。
-
RubyGems 3.5.3
-
abbrev 0.1.2
-
base64 0.2.0
-
benchmark 0.3.0
-
bigdecimal 3.1.5
-
bundler 2.5.3
-
cgi 0.4.1
-
csv 3.2.8
-
date 3.3.4
-
delegate 0.3.1
-
drb 2.2.0
-
english 0.8.0
-
erb 4.0.3
-
error_highlight 0.6.0
-
etc 1.4.3
-
fcntl 1.1.0
-
fiddle 1.1.2
-
fileutils 1.7.2
-
find 0.2.0
-
getoptlong 0.2.1
-
io-console 0.7.1
-
io-nonblock 0.3.0
-
io-wait 0.3.1
-
ipaddr 1.2.6
-
irb 1.11.0
-
json 2.7.1
-
logger 1.6.0
-
mutex_m 0.2.0
-
net-http 0.4.0
-
net-protocol 0.2.2
-
nkf 0.1.3
-
observer 0.1.2
-
open-uri 0.4.1
-
open3 0.2.1
-
openssl 3.2.0
-
optparse 0.4.0
-
ostruct 0.6.0
-
pathname 0.3.0
-
pp 0.5.0
-
prettyprint 0.2.0
-
pstore 0.1.3
-
psych 5.1.2
-
rdoc 6.6.2
-
readline 0.0.4
-
reline 0.4.1
-
resolv 0.3.0
-
rinda 0.2.0
-
securerandom 0.3.1
-
set 1.1.0
-
shellwords 0.2.0
-
singleton 0.2.0
-
stringio 3.1.0
-
strscan 3.0.7
-
syntax_suggest 2.0.0
-
syslog 0.1.2
-
tempfile 0.2.1
-
time 0.3.0
-
timeout 0.4.1
-
tmpdir 0.2.0
-
tsort 0.2.0
-
un 0.3.0
-
uri 0.13.0
-
weakref 0.1.3
-
win32ole 1.8.10
-
yaml 0.3.0
-
zlib 3.1.0
以下捆绑 gem 已从默认 gem 中提升。
-
racc 1.7.3
以下捆绑 gem 已更新。
-
minitest 5.20.0
-
rake 13.1.0
-
test-unit 3.6.1
-
rexml 3.2.6
-
rss 0.3.0
-
net-ftp 0.3.3
-
net-imap 0.4.9
-
net-smtp 0.4.0
-
rbs 3.4.0
-
typeprof 0.21.9
-
debug 1.9.1
有关默认 gem 或捆绑 gem 的详细信息,请参阅 GitHub 版本,例如 Logger 或更改日志。
Prism
¶ ↑
-
引入了 Prism 解析器 作为默认 gem
-
Prism
是一个可移植、容错且可维护的 Ruby 语言递归下降解析器
-
-
如果您有兴趣贡献,可以向 Prism 仓库 发送 pull request 或 issue。
-
您现在可以使用
ruby --parser=prism
或RUBYOPT="--parser=prism"
来尝试使用Prism
编译器。请注意,此标志仅用于调试。
兼容性问题¶ ↑
-
通过以下文件打开方法创建/派生子进程已弃用。[Feature #19630]
-
当给定非 lambda、非字面量块时,
Kernel#lambda
现在会抛出ArgumentError
,而不是返回未修改的块。自 Ruby 3.0.0 起,这些用法已在Warning[:deprecated]
类别下发出警告。[Feature #19777] -
RUBY_GC_HEAP_INIT_SLOTS
环境变量已弃用并已删除。应改用环境变量RUBY_GC_HEAP_%d_INIT_SLOTS
。[Feature #19785] -
在没有普通参数的块中,不带参数的
it
调用已弃用。在 Ruby 3.4 中,it
将是第一个块参数的引用。[Feature #18980] -
NoMethodError
的错误消息已更改,不再使用目标对象的#inspect
来提高效率,而是说 "instance of ClassName"。[Feature #18285]([1] * 100).nonexisting # undefined method `nonexisting' for an instance of Array (NoMethodError)
-
现在,在使用匿名参数的块中不允许匿名参数转发。[Feature #19370]
标准库兼容性问题¶ ↑
-
racc
已升级为捆绑 gem。-
如果您在 bundler 环境下使用
racc
,则需要在Gemfile
中添加racc
。
-
-
ext/readline
已退休-
我们有
reline
,它是一个与ext/readline
API 兼容的纯 Ruby 实现。将来我们将依赖reline
。如果您需要使用ext/readline
,可以通过 rubygems.org 使用gem install readline-ext
安装ext/readline
。 -
我们不再需要安装
libreadline
或libedit
等库。
-
C API 更新¶ ↑
-
rb_postponed_job
更新 -
新增 API 和弃用 API(详情请见注释)
-
新增:
rb_postponed_job_preregister()
-
新增:
rb_postponed_job_trigger()
-
弃用:
rb_postponed_job_register()
(语义更改,见下文) -
弃用:
rb_postponed_job_register_one()
-
新增:
rb_postponed_job_preregister()
-
新增:
rb_postponed_job_trigger()
-
弃用:
rb_postponed_job_register()
(语义更改,见下文) -
弃用:
rb_postponed_job_register_one()
-
-
延迟作业 API 已更改,以解决一些罕见的崩溃问题。为了解决这个问题,我们引入了两个新的 API 并弃用了当前的 API。这些函数的语义也略有变化;
rb_postponed_job_register
现在与once
变体类似,即使用相同的func
进行多次调用可能会合并为对func
的单次执行 [Feature #20057] -
内部线程事件钩子 API 的一些更新
-
rb_internal_thread_event_data_t
包含目标 Ruby 线程(VALUE)和回调函数(rb_internal_thread_event_callback
)。github.com/ruby/ruby/pull/8885 -
以下函数用于从内部线程事件钩子 API 操作 Ruby 线程局部数据(它们是在 Ruby 3.2 中引入的)。github.com/ruby/ruby/pull/8936
-
rb_internal_thread_specific_key_create()
-
rb_internal_thread_specific_get()
-
rb_internal_thread_specific_set()
-
-
rb_profile_thread_frames()
用于从特定线程获取帧。[Feature #10602] -
rb_data_define()
用于定义Data
。[Feature #19757] -
rb_ext_resolve_symbol()
用于从扩展库中搜索函数。[Feature #20005] -
IO
相关更新 -
rb_io_t
的详细信息将被隐藏,并且为每个成员添加了弃用属性。[Feature #19057] -
rb_io_path(VALUE io)
用于获取io
的路径。 -
rb_io_closed_p(VALUE io)
用于获取io
的打开或关闭状态。 -
rb_io_mode(VALUE io)
用于获取io
的模式。 -
rb_io_open_descriptor()
用于从文件描述符创建IO
对象。
实现改进¶ ↑
解析器¶ ↑
-
用 Lrama LALR 解析器生成器 替换 Bison。不再需要安装 Bison 才能从源代码构建 Ruby。我们不再会遇到 Bison 兼容性问题,并且可以通过在 Lrama 中实现新功能来使用它们。[功能 #19637]
-
有关详细信息,请参阅 Ruby 解析器的未来愿景。
-
Lrama 内部解析器是使用 Racc 生成的 LR 解析器,以确保可维护性。
-
支持参数化规则
(?, *, +)
,它将用于 Ruby parse.y。
GC
/ 内存管理¶ ↑
-
与 Ruby 3.2 相比,性能大幅提升。
-
引入了一个新的
REMEMBERED_WB_UNPROTECTED_OBJECTS_LIMIT_RATIO
调整变量来控制导致主要GC
收集触发的未保护对象数量。默认设置为0.01
(1%)。这显著降低了主要GC
收集的频率。[功能 #19571] -
为许多缺少写屏障的核心类型实现了写屏障,特别是
Time
、Enumerator
、MatchData
、Method
、File::Stat
、BigDecimal
和其他一些类型。这显著减少了次要GC
收集时间和主要GC
收集频率。 -
现在大多数核心类都使用可变宽度分配,特别是
Hash
、Time
、Thread::Backtrace
、Thread::Backtrace::Location
、File::Stat
、Method
。这使得这些类分配和释放速度更快,使用更少的内存并减少堆碎片。
-
defined?(@ivar)
使用Object
形状进行了优化。
YJIT¶ ↑
-
与 Ruby 3.2 相比,性能大幅提升。
-
对 splat 和 rest 参数的支持已得到改进。
-
为虚拟机的堆栈操作分配寄存器。
-
编译了更多具有可选参数的调用。还编译了
Exception
处理程序。 -
不支持的调用类型和巨型调用站点不再退出到解释器。
-
内联了基本的 Rails 方法,如
#blank?
和 {专门的#present?
}。 -
Integer#*
、Integer#!=
、String#!=
、String#getbyte
、Kernel#block_given?
、Kernel#is_a?
、Kernel#instance_of?
和Module#===
进行了特殊优化。 -
编译速度现在比 Ruby 3.2 稍快。
-
现在在 Optcarrot 上比解释器快 3 倍以上!
-
与 Ruby 3.2 相比,内存使用量显著提高
-
编译代码的元数据使用的内存更少。
-
当应用程序拥有超过 40,000 个 ISEQ 时,
--yjit-call-threshold
会自动从 30 提升至 120。 -
添加了
--yjit-cold-threshold
用于跳过编译冷 ISEQ。 -
在 Arm64 上生成了更紧凑的代码。
-
-
代码
GC
现在默认情况下已禁用 -
--yjit-exec-mem-size
被视为硬性限制,编译新代码将在此限制下停止。 -
如果需要,您仍然可以使用
--yjit-code-gc
启用代码GC
-
添加
RubyVM::YJIT.enable
,可以在运行时启用 YJIT -
您可以启动 YJIT,而无需修改命令行参数或环境变量。Rails 7.2 将 默认启用 YJIT,使用此方法。
-
这也可以用于仅在应用程序完成启动后才启用 YJIT。如果您想在启动时禁用 YJIT,但同时使用其他 YJIT 选项,则可以使用
--yjit-disable
。 -
默认情况下,提供更多 YJIT 统计信息
-
yjit_alloc_size
和其他几个与元数据相关的统计信息现在默认情况下可用。 -
--yjit-stats
生成的ratio_in_yjit
统计信息现在在发布版本中可用,不再需要特殊的统计信息或开发版本来访问大多数统计信息。 -
添加更多分析功能
-
添加了
--yjit-perf
用于简化使用 Linux perf 进行分析。 -
--yjit-trace-exits
现在支持使用--yjit-trace-exits-sample-rate=N
进行采样。 -
更彻底的测试和多个错误修复
-
添加了
--yjit-stats=quiet
用于避免在退出时打印统计信息。
MJIT¶ ↑
-
已删除 MJIT。
-
已删除
--disable-jit-support
。请考虑改用--disable-yjit --disable-rjit
。
-
RJIT¶ ↑
-
引入了纯 Ruby JIT 编译器 RJIT。
-
RJIT 仅支持 Unix 平台上的 x86_64 架构。
-
与 MJIT 不同,它在运行时不需要 C 编译器。
-
-
RJIT 仅用于实验目的。
-
您应该在生产环境中继续使用 YJIT。
-
M:N Thread
调度器¶ ↑
-
引入了 M:N
Thread
调度器。[功能 #19842]-
背景:Ruby 1.8 及更早版本使用 M:1 线程调度器(M 个 Ruby 线程与 1 个原生线程。称为用户级线程或绿色线程)。Ruby 1.9 及更高版本使用 1:1 线程调度器(1 个 Ruby 线程与 1 个原生线程)。与 1:1 线程相比,M:1 线程占用更少的资源,因为它只需要 1 个原生线程。但是,很难为所有阻塞操作提供上下文切换支持,因此从 Ruby 1.9 开始采用 1:1 线程。M:N 线程调度器为 M 个 Ruby 线程使用 N 个原生线程(通常 N 是一个小数字)。它不需要与 Ruby 线程数量相同的原生线程(类似于 M:1 线程调度器)。此外,我们的 M:N 线程与 1:1 线程一样,很好地支持阻塞操作。有关更多详细信息,请参阅工单。我们的 M:N 线程调度器参考了 Go 语言中的 goroutine 调度器。
-
在 ractor 中,由于实现原因,一次只能运行 1 个线程。因此,仅使用一个
Ractor
的应用程序(大多数应用程序)M:N 线程调度器将作为 M:1 线程调度器工作,并从 Ruby 1.8 进一步扩展。 -
M:N 线程调度器可能会引入 C 扩展的不兼容性,因此在主 Ractor 上默认情况下禁用它。
RUBY_MN_THREADS=1
环境变量将启用它。在非主 Ractor 上,M:N 线程调度器已启用(目前无法禁用它)。 -
N
(原生线程数量)可以通过RUBY_MAX_CPU
环境变量指定。默认值为 8。请注意,使用超过N
个原生线程来支持多种阻塞操作。
-