Ruby 3.4.0 发布

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

引入 it

添加 it 来引用没有变量名的代码块参数。[特性 #18980]

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

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

it 的行为与 _1 非常相似。当意图仅在代码块中使用 _1 时,可能出现其他编号的参数(如 _2)会对读者增加额外的认知负担。因此,引入 it 作为方便的别名。在简单的场景中使用 it,其中 it 本身就说明了一切,例如在一行代码块中。

Prism 现在是默认解析器

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

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

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

套接字库现在具有 Happy Eyeballs Version 2 (RFC 8305)

套接字库现在具有 Happy Eyeballs Version 2 (RFC 8305),这是在许多编程语言中广泛采用的用于改进连接性的最新标准化版本,在 TCPSocket.new (TCPSocket.open) 和 Socket.tcp 中。此改进使 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 平台上,大多数基准测试的性能都得到了提升。
  • 通过压缩的元数据和统一的内存限制,减少了内存使用。
  • 各种错误修复: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#eachArray#selectArray#map 用 Ruby 重写以获得更好的性能。[特性 #20182]。
  • 能够内联小型/简单方法,例如
    • 空方法
    • 返回常量的方法
    • 返回 self 的方法
    • 直接返回参数的方法
  • 为更多运行时方法提供专门的代码生成
  • 优化 String#getbyteString#setbyte 和其他字符串方法
  • 优化按位运算以加速低级位/字节操作
  • 支持在多 Ractor 模式下共享常量
  • 各种其他增量优化

模块化 GC

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

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

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

语言变更

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

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

  • 不再允许在索引中传递代码块。[错误 #19918]

  • 不再允许在索引中使用关键字参数。[错误 #20218]

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

核心类更新

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

  • Exception

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

    • 添加了 GC.config 以允许在垃圾收集器上设置配置变量。[特性 #20443]

    • 引入了 GC 配置参数 rgengc_allow_full_mark。当 false 时,GC 将仅标记年轻对象。默认为 true。[特性 #20443]

  • Ractor

    • 允许在 Ractor 中使用 require。加载过程将在主 Ractor 上运行。添加了 Ractor._require(feature) 以在主 Ractor 上运行加载过程。[特性 #20627]

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

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

    • 添加了 Ractor.store_if_absent(key){ init } 以在线程安全中初始化 ractor 局部变量。[特性 #20875]

  • Range

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

标准库更新

注意:我们仅列出标准库的重大更新。

  • RubyGems
    • 为 gem push 添加 --attestation 选项。它使能够将签名存储到 sigstore.dev
  • Bundler
    • 添加 lockfile_checksums 配置,以将校验和包含在新的锁文件中
    • 添加 bundle lock --add-checksums 以将校验和添加到现有锁文件中
  • JSON

    • JSON.parse 的性能提升,比 json-2.7.x 快约 1.5 倍。
  • Tempfile

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

兼容性问题

注意:不包括功能缺陷修复。

  • 错误消息和回溯显示已更改。
    • 使用单引号代替反引号作为起始引号。[功能 #16495]
    • 在方法名称之前显示类名称(仅当该类具有永久名称时)。[功能 #19117]
    • Kernel#callerThread::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 的渲染方式已更改。[错误 #20433]

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

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

    "1.".to_f    #=> 1.0
    "1.E-1".to_f #=> 0.1 (previously, 1.0 was returned)
    
  • Refinement#refined_class 已删除。[功能 #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

  • URI

    • 默认解析器从符合 RFC 2396 标准切换为符合 RFC 3986 标准。[错误 #19266]

C API 更新

  • rb_newobjrb_newobj_of(以及相应的宏 RB_NEWOBJRB_NEWOBJ_OFNEWOBJNEWOBJ_OF)已被删除。[功能 #20265]
  • 删除了已弃用的函数 rb_gc_force_recycle。[功能 #18290]

其他更改

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

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

有关更多详细信息,请参阅 NEWS提交日志

经过这些更改,自 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 开发中。