Ruby 3.4.0 已发布

naruse 于 2024 年 12 月 25 日发布

我们很高兴地宣布 Ruby 3.4.0 的发布。Ruby 3.4 增加了 it 块参数引用,将 Prism 作为默认解析器,为 socket 库增加了 Happy Eyeballs Version 2 支持,改进了 YJIT,增加了 Modular GC 等。

it 已引入

it 被添加到引用一个没有变量名的块参数。 [Feature #18980]

ary = ["foo", "bar", "baz"]

p ary.map { it.upcase } #=> ["FOO", "BAR", "BAZ"]

it 的行为非常类似于 _1。当只想在块中使用 _1 时,可能出现的其他编号参数,如 _2,会增加读者的认知负担。因此,引入 it 作为一种方便的别名。在 it 不言自明的情况下,例如在单行块中,可以使用 it

Prism 现在是默认的解析器

将默认解析器从 parse.y 切换到 Prism。 [Feature #20564]

这是一个内部改进,用户应该几乎看不到变化。如果您注意到任何兼容性问题,请向我们报告。

要使用传统的解析器,请使用命令行参数 --parser=parse.y

socket 库现在支持 Happy Eyeballs Version 2 (RFC 8305)

socket 库现在在 TCPSocket.new (TCPSocket.open) 和 Socket.tcp 中支持 Happy Eyeballs Version 2 (RFC 8305),这是在许多编程语言中广泛采用的、用于改善连接性的最新标准化版本。此改进使 Ruby 能够提供高效可靠的网络连接,适应现代互联网环境。

在 Ruby 3.3 之前,这些方法串行执行名称解析和连接尝试。使用此算法,它们现在将按如下方式运行:

  1. 并发执行 IPv6 和 IPv4 名称解析
  2. 尝试连接到已解析的 IP 地址,优先 IPv6,以 250 毫秒的间隔进行并行尝试
  3. 返回第一个成功的连接,同时取消任何其他连接

这确保了最小化的连接延迟,即使特定协议或 IP 地址延迟或不可用。此功能默认启用,因此无需额外配置即可使用。要全局禁用它,请设置环境变量 RUBY_TCP_NO_FAST_FALLBACK=1 或调用 Socket.tcp_fast_fallback=false。或者,要在每个方法的基础上禁用它,请使用关键字参数 fast_fallback: false

YJIT

简而言之

  • 在 x86-64 和 arm64 平台上,大多数基准测试的性能都有所提高。
  • 通过压缩的元数据和统一的内存限制,减少了内存使用。
  • 各种 bug 修复:YJIT 现在更加健壮,经过了更彻底的测试。

新功能

  • 命令行选项
    • --yjit-mem-size 引入了一个统一的内存限制(默认为 128MiB),用于跟踪 YJIT 的总内存使用情况,比旧的 --yjit-exec-mem-size 选项更直观。
    • --yjit-log 启用编译日志,用于跟踪正在编译的内容。
  • Ruby API
    • RubyVM::YJIT.log 提供了在运行时访问编译日志尾部的方法。
  • YJIT 统计信息
    • RubyVM::YJIT.runtime_stats 现在始终提供关于无效化、内联和元数据编码的附加统计信息。

新的优化

  • 压缩上下文减少了存储 YJIT 元数据所需的内存
  • 为局部变量和 Ruby 方法参数分配寄存器
  • 当启用 YJIT 时,使用更多用 Ruby 编写的核心原语
    • Array#each, Array#select, Array#map 用 Ruby 重写,以提高性能 [Feature #20182]。
  • 能够内联小型/琐碎的方法,例如:
    • 空方法
    • 返回常量的 nil 方法
    • 返回 self 的 nil 方法
    • 直接返回参数的 nil 方法
  • 为更多运行时方法进行专门的代码生成
  • 优化 String#getbyte, String#setbyte 和其他字符串 nil 方法
  • 优化按位运算以加速低级位/字节操作
  • 支持多 Ractor 模式下的可共享常量
  • 各种其他渐进式优化

模块化 GC

  • 可以通过模块化垃圾回收功能动态加载备用垃圾回收器 (GC) 实现。要启用此功能,请在构建时使用 --with-modular-gc 配置 Ruby。可以使用环境变量 RUBY_GC_LIBRARY 在运行时加载 GC 库。 [Feature #20351]

  • Ruby 的内置垃圾回收器已拆分为单独的文件 gc/default/default.c,并使用 gc/gc_impl.h 中定义的 API 与 Ruby 交互。内置垃圾回收器现在也可以使用 make modular-gc MODULAR_GC=default 构建为库,并使用环境变量 RUBY_GC_LIBRARY=default 启用。 [Feature #20470]

  • 提供了一个基于 MMTk 的实验性 GC 库。此 GC 库可以使用 make modular-gc MODULAR_GC=mmtk 构建,并使用环境变量 RUBY_GC_LIBRARY=mmtk 启用。这需要在构建机器上安装 Rust 工具链。 [Feature #20860]

语言更改

  • 在没有 frozen_string_literal 注释的文件中的字符串字面量,在被修改时会发出警告。这些警告可以通过 -W:deprecated 或设置 Warning[:deprecated] = true 来启用。要禁用此更改,可以使用 --disable-frozen-string-literal 命令行参数运行 Ruby。 [Feature #20205]

  • 现在支持在调用方法时将关键字散列 nil**nil 的处理方式类似于 **{},不传递任何关键字,也不调用任何转换方法。 [Bug #20064]

  • 在索引中不再允许传递块。 [Bug #19918]

  • 在索引中不再允许关键字参数。 [Bug #20218]

  • 顶层名称 ::Ruby 现在被保留,当定义它时会发出 Warning[:deprecated] 警告。 [Feature #20884]

核心类更新

注意:我们仅列出核心类的重要更新。

  • 异常

    • Exception#set_backtrace 现在接受 Thread::Backtrace::Location 数组。Kernel#raiseThread#raiseFiber#raise 也接受这种新格式。 [Feature #13557]
  • GC

    • 添加了 GC.config 以允许设置垃圾回收器的配置变量。 [Feature #20443]

    • 引入了 GC 配置参数 rgengc_allow_full_mark。当为 false 时,GC 只会标记年轻对象。默认值为 true。 [Feature #20443]

  • Ractor

    • 允许在 Ractor 中使用 requirerequire 操作将在主 Ractor 上运行。添加了 Ractor._require(feature) 以在主 Ractor 上运行 require 操作。 [Feature #20627]

    • 添加了 Ractor.main?。 [Feature #20627]

    • 添加了 Ractor.[]Ractor.[]= 来访问当前 Ractor 的 ractor 本地存储。 [Feature #20715]

    • 添加了 Ractor.store_if_absent(key){ init } 以以线程安全的方式初始化 ractor 本地变量。 [Feature #20875]

  • Range

    • Range#size 现在如果范围不可迭代,将引发 TypeError。 [Misc #18984]

标准库更新

注意:我们只列出了标准库中的重要更新。

  • RubyGems
    • 为 gem push 添加了 --attestation 选项。它使得可以将签名存储到 sigstore.dev
  • Bundler
    • 添加了 lockfile_checksums 配置,以便在新的 lockfile 中包含校验和
    • 添加了 bundle lock --add-checksums 命令,用于将校验和添加到现有的 lockfile
  • JSON

    • 性能改进:JSON.parse 比 json-2.7.x 快约 1.5 倍。
  • Tempfile

    • 为 Tempfile.create 实现的关键字参数 anonymous: trueTempfile.create(anonymous: true) 会立即删除创建的临时文件。因此应用程序无需删除文件。 [Feature #20497]
  • win32/sspi.rb

以下捆绑 gem 已从默认 gem 升级。

  • mutex_m 0.3.0
  • getoptlong 0.2.1
  • base64 0.2.0
  • bigdecimal 3.1.8
  • observer 0.1.2
  • abbrev 0.1.2
  • resolv-replace 0.1.1
  • rinda 0.2.0
  • drb 2.2.1
  • nkf 0.2.0
  • syslog 0.2.0
  • csv 3.3.2
  • repl_type_completor 0.1.9

兼容性问题

注意:不包括功能错误修复。

  • 错误消息和回溯显示已更改。
    • 使用单引号而不是反引号作为开引号。 [Feature #16495]
    • 在方法名前显示类名(仅当类具有永久名称时)。 [Feature #19117]
    • Kernel#caller, Thread::Backtrace::Location 的方法等也相应进行了更改。
    Old:
    test.rb:1:in `foo': undefined method `time' for an instance of Integer
            from test.rb:2:in `<main>'
    
    New:
    test.rb:1:in 'Object#foo': undefined method 'time' for an instance of Integer
            from test.rb:2:in '<main>'
    
  • Hash#inspect 的渲染已更改。 [Bug #20433]

    • 符号键使用现代符号键语法显示:"{user: 1}"
    • 其他键现在 => 两侧有空格:'{"user" => 1}',而以前没有:'{"user"=>1}'
  • Kernel#Float() 现在接受省略小数部分的十进制字符串。 [Feature #20705]

    Float("1.")    #=> 1.0 (previously, an ArgumentError was raised)
    Float("1.E-1") #=> 0.1 (previously, an ArgumentError was raised)
    
  • String#to_f 现在接受省略小数部分的十进制字符串。请注意,当指定指数时,结果会发生变化。 [Feature #20705]

    "1.".to_f    #=> 1.0
    "1.E-1".to_f #=> 0.1 (previously, 1.0 was returned)
    
  • Refinement#refined_class 已被移除。 [Feature #19714]

标准库兼容性问题

  • DidYouMean

    • DidYouMean::SPELL_CHECKERS[]=DidYouMean::SPELL_CHECKERS.merge! 已被移除。
  • Net::HTTP

    • 移除了以下已弃用的常量
      • Net::HTTP::ProxyMod
      • Net::NetPrivate::HTTPRequest
      • Net::HTTPInformationCode
      • Net::HTTPSuccessCode
      • Net::HTTPRedirectionCode
      • Net::HTTPRetriableCode
      • Net::HTTPClientErrorCode
      • Net::HTTPFatalErrorCode
      • Net::HTTPServerErrorCode
      • Net::HTTPResponseReceiver
      • Net::HTTPResponceReceiver

      这些常量自 2012 年起已被弃用。

  • Timeout

    • 拒绝 Timeout.timeout 的负值。 [Bug #20795]
  • URI

    • 将默认解析器从符合 RFC 2396 更改为符合 RFC 3986。 [Bug #19266]

C API 更新

  • rb_newobjrb_newobj_of(以及相应的宏 RB_NEWOBJ, RB_NEWOBJ_OF, NEWOBJ, NEWOBJ_OF)已被移除。 [Feature #20265]
  • 移除了已弃用的函数 rb_gc_force_recycle。 [Feature #18290]

其他更改

  • 将块传递给不使用该块的方法将在详细模式 (-w) 下显示警告。 [Feature #15554]

  • 重新定义某些被解释器和 JIT 特别优化的核心方法,如 String.freezeInteger#+,现在会发出性能类警告(-W:performanceWarning[:performance] = true)。 [Feature #20429]

有关更多详细信息,请参阅 NEWScommit logs

这些更改使得自 Ruby 3.3.0 以来,4942 个文件已更改,插入了 202244 行(+),删除了 255528 行(-)

圣诞快乐,节日快乐,祝您使用 Ruby 3.4 编程愉快!

下载

  • https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.0.tar.gz

    SIZE: 23153022
    SHA1: 8ccb561848a7c460ae08e1a120a47c4a88a79335
    SHA256: 068c8523442174bd3400e786f4a6952352c82b1b9f6210fd17fb4823086d3379
    SHA512: bc70ecba27d1cdea00879f03487cad137a7d9ab2ad376cfb7a65780ad14da637fa3944eeeede2c04ab31eeafb970c64ccfeeb854c99c1093937ecc1165731562
    
  • https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.0.tar.xz

    SIZE: 17215572
    SHA1: eb25447cc404e8d2e177c62550d0224ebd410e68
    SHA256: 0081930db22121eb997207f56c0e22720d4f5d21264b5907693f516c32f233ca
    SHA512: 776a2cf3e9ccc77c27500240f168aa3e996b0c7c1ee1ef5a7afc291a06c118444016fde38b5b139c0b800496b8eb1b5456562d833f0edc0658917164763b1af7
    
  • https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.0.zip

    SIZE: 28310193
    SHA1: 26254ca5d3decc28a4e5faec255995265e5270b5
    SHA256: c120228038af04554f6363e716b0a32cbf53cf63c6adf9f2c22a24f43dc8b555
    SHA512: 4d535ed10db76a6aa74f8a025df319deb28483a7a781c24045906ee7663f1cff9d9f9e71dbc993c9e050113a34b37c7fa2143c355a0a6e1e1029bf2c92213ecc
    

什么是 Ruby

Ruby 最初由 Matz (Yukihiro Matsumoto) 于 1993 年开发,现在作为开源项目进行开发。它运行在多个平台上,并在世界各地广泛使用,尤其是在 Web 开发领域。

近期新闻

Ruby 4.0.0 发布

我们很高兴地宣布 Ruby 4.0.0 的发布。Ruby 4.0 引入了“Ruby Box”和“ZJIT”,并增加了许多改进。

naruse 发布于 2025 年 12 月 25 日

Ruby 文档的全新外观

继 ruby-lang.org 重新设计之后,我们还有更多好消息来庆祝 Ruby 成立 30 周年:docs.ruby-lang.org 采用了 Aliki——RDoc 的新默认主题,焕然一新。

Stan Lo 发布于 2025 年 12 月 23 日

重新设计我们的网站标识

我们很高兴地宣布对我们的网站进行全面重新设计。此次更新的设计由 Akatsuka Taeko 创作。

Hiroshi SHIBATA 发布于 2025 年 12 月 22 日

Ruby 4.0.0 preview3 发布

我们很高兴地宣布 Ruby 4.0.0-preview3 的发布。Ruby 4.0 引入了 Ruby::Box 和“ZJIT”,并增加了许多改进。

naruse 发布于 2025 年 12 月 18 日

更多新闻...