NEWS for Ruby 2.7.0

本文件列出了发布版本之间用户可见的功能变更,不包括错误修复。

请注意,每个条目都保持简短,没有提供任何原因或参考信息。有关所有足够信息的完整变更列表,请参阅 ChangeLog 文件或 Redmine(例如:https://bugs.ruby-lang.org/issues/$FEATURE_OR_BUG_NUMBER)。

自 2.6.0 版本以来的变更

语言变更

模式匹配

关键字参数的规范已更改为 3.0

编号参数

没有块的 proc/lambda 已弃用

其他杂项更改

命令行选项

Warning 选项

-W 选项已扩展为包含后面的 :,用于管理分类警告。[特性 #16345] [特性 #16420]

另请参见 Warning核心类更新 中。

核心类更新(仅突出显示的更新)

数组
新方法
可比较
修改后的方法
  • Comparable#clamp 现在接受 Range 参数。[特性 #14784]

    -1.clamp(0..2) #=> 0
     1.clamp(0..2) #=> 1
     3.clamp(0..2) #=> 2
    # With beginless and endless ranges:
    -1.clamp(0..)  #=> 0
     3.clamp(..2)  #=> 2
    
复数
新方法
  • 添加了 Complex#<=>。因此 0 <=> 0i 将不会引发 NoMethodError。[错误 #15857]

目录
修改的方法
  • Dir.globDir.[] 不再允许使用 NUL 分隔的 glob 模式。请使用 Array 代替。[特性 #14643]

编码
新的编码
  • 添加了新的编码 CESU-8。[特性 #15931]

可枚举
新方法
  • 添加了 Enumerable#filter_map。[特性 #15323]

    [1, 2, 3].filter_map {|x| x.odd? ? x.to_s : nil } #=> ["1", "3"]
    
  • 添加了 Enumerable#tally。[特性 #11076]

    ["A", "B", "C", "B", "A"].tally #=> {"A"=>2, "B"=>2, "C"=>1}
    
枚举器
新方法
  • 添加了 Enumerator.produce,用于从任何自定义数据转换生成 Enumerator。[特性 #14781]

    require "date"
    dates = Enumerator.produce(Date.today, &:succ) #=> infinite sequence of dates
    dates.detect(&:tuesday?) #=> next Tuesday
    
  • 添加了 Enumerator::Lazy#eager,用于从惰性枚举器生成非惰性枚举器。[特性 #15901]

    a = %w(foo bar baz)
    e = a.lazy.map {|x| x.upcase }.map {|x| x + "!" }.eager
    p e.class               #=> Enumerator
    p e.map {|x| x + "?" }  #=> ["FOO!?", "BAR!?", "BAZ!?"]
    
  • 添加了 Enumerator::Yielder#to_proc,以便 Yielder 对象可以作为块参数直接传递给另一个方法。[特性 #15618]

  • 添加了 Enumerator::Lazy#with_index 为惰性 以前,Enumerator::Lazy#with_index 未定义,因此它从 Enumerator 中获取了默认实现,该实现不是惰性的。[Bug #7877]

    ("a"..).lazy.with_index(1) { |it, index| puts "#{index}:#{it}" }.take(3).force
    # => 1:a
    #    2:b
    #    3:c
    
纤维
新方法
文件
新方法
  • 添加了 File.absolute_path?,用于以可移植的方式检查路径是否为绝对路径。[特性 #15868]

    File.absolute_path?("/foo")   # => true (on *nix)
    File.absolute_path?("C:/foo") # => true (on Windows)
    File.absolute_path?("foo")    # => false
    
修改后的方法
  • File.extname 现在在非 Windows 平台上返回以点结尾的名称的点字符串。[Bug #15267]

    File.extname("foo.") #=> "."
    
FrozenError
新方法
GC
新方法
  • 添加了 GC.compact 方法用于压缩堆。此函数压缩堆中的活动对象,以便可以使用更少的页面,并且堆可能更适合 CoW(写时复制)。[特性 #15626]

    有关算法和注意事项的详细信息,请参阅:bugs.ruby-lang.org/issues/15626

IO
新方法
整数
修改后的方法
  • Integer#[] 现在支持范围操作。[特性 #8842]

    0b01001101[2, 4]  #=> 0b0011
    0b01001100[2..5]  #=> 0b0011
    0b01001100[2...6] #=> 0b0011
    #   ^^^^
    
方法
修改后的方法
模块
新方法
  • 添加了 Module#const_source_location 用于检索定义常量的所在位置。[特性 #10771]

  • 添加了 Module#ruby2_keywords 用于将方法标记为通过常规参数 splat 传递关键字参数,这在以与旧版 Ruby 版本向后兼容的方式将所有参数委托给另一个方法时很有用。[Bug #16154]

修改的方法
NilClass / TrueClass / FalseClass
修改的方法
ObjectSpace::WeakMap
修改后的方法
Proc
新方法
  • 添加了 Proc#ruby2_keywords 用于将 proc 标记为通过常规参数 splat 传递关键字参数,这在以与旧版 Ruby 版本向后兼容的方式将所有参数委托给另一个方法或 proc 时很有用。[特性 #16404]

Range
新方法
修改后的方法
RubyVM
已移除方法
  • RubyVM.resolve_feature_path 已移至 $LOAD_PATH.resolve_feature_path。[功能 #15903] [功能 #15230]

字符串
Unicode
  • 将 Unicode 版本和 Emoji 版本从 11.0.0 更新至 12.0.0。[功能 #15321]

  • 将 Unicode 版本更新至 12.1.0,添加对 U+32FF 方块时代名称令和的支持。[功能 #15195]

  • 将 Unicode Emoji 版本更新至 12.1。[功能 #16272]

符号
新方法
时间
新方法
修改后的方法
未绑定方法
新方法
  • 添加了 UnboundMethod#bind_call 方法。[功能 #15955]

    umethod.bind_call(obj, ...) 在语义上等效于 umethod.bind(obj).call(...)。这种习惯用法在一些库中用于调用被覆盖的方法。添加的方法执行相同的操作,但不会分配中间的 Method 对象。

    class Foo
      def add_1(x)
        x + 1
      end
    end
    class Bar < Foo
      def add_1(x) # override
        x + 2
      end
    end
    
    obj = Bar.new
    p obj.add_1(1) #=> 3
    p Foo.instance_method(:add_1).bind(obj).call(1) #=> 2
    p Foo.instance_method(:add_1).bind_call(obj, 1) #=> 2
    
警告
新方法
  • 添加了 Warning.[]Warning.[]= 来管理发出/抑制某些类别的警告。[功能 #16345] [功能 #16420]

$LOAD_PATH
新方法
  • 添加了 $LOAD_PATH.resolve_feature_path。[功能 #15903] [功能 #15230]

标准库更新(仅突出显示的更新)

Bundler
CGI
CSV
日期
  • Date.jisx0301、Date#jisx0301 和 Date.parse 支持新的日本时代。[功能 #15742]

委托
  • Object#DelegateClass 接受一个块,并在返回的类上下文中对其进行模块评估,类似于 Class.newStruct.new.

ERB
  • 禁止对 ERB 实例进行封存。

IRB
  • 引入受 Pry gem 启发的语法高亮,用于 Binding#irb 源代码行、REPL 输入和一些核心类对象的检查输出。

  • 引入由 Reline 提供的多行编辑模式。

  • 在完成时显示文档。

  • 默认情况下启用自动缩进和保存/加载历史记录。

JSON
  • 升级到 2.3.0。

Net::FTP
  • 添加 Net::FTP#features 用于检查可用功能,以及 Net::FTP#option 用于启用/禁用每个功能。[功能 #15964]

Net::HTTP
  • 在 Net::HTTP#start 中添加 ipaddr 可选参数,以替换 TCP/IP 连接的地址。[功能 #5180]

Net::IMAP
  • 添加服务器名称指示 (SNI) 支持。[功能 #15594]

open-uri
  • 警告 open-uri 的“open”方法在 Kernel 中。使用 URI.open 代替。[杂项 #15893]

  • “text/*” 媒体类型的默认字符集为 UTF-8,而不是 ISO-8859-1。[错误 #15933]

OptionParser
  • 现在为未知选项显示“您是说?”。[功能 #16256]

    test.rb

    require "optparse"
    OptionParser.new do |opts|
      opts.on("-f", "--foo", "foo") {|v| }
      opts.on("-b", "--bar", "bar") {|v| }
      opts.on("-c", "--baz", "baz") {|v| }
    end.parse!
    

    示例

    $ ruby test.rb --baa
    Traceback (most recent call last):
    test.rb:7:in `<main>': invalid option: --baa (OptionParser::InvalidOption)
    Did you mean?  baz
                   bar
Pathname
  • Pathname.glob 现在将 3 个参数委托给 Dir.glob 以接受 base 关键字。[功能 #14405]

Racc
  • 从上游存储库合并 1.4.15 并添加了 racc 的 cli。

Reline
  • 新的标准库,与 readline 标准库兼容,但用纯 Ruby 实现。它还提供多行编辑模式。

REXML
RSS
RubyGems
StringScanner

兼容性问题(不包括功能错误修复)

Proc
  • Proc#to_s 的格式已更改。[功能 #16101]

Range
  • Range#minmax 以前用于迭代范围以确定最大值。现在它使用与 Range#max 相同的算法。在极少数情况下(例如,浮点数或字符串的范围),这可能会产生不同的结果。[Bug #15807]

标准库兼容性问题(不包括功能错误修复)

pathname
  • 当使用 Pathname 参数调用 Kernel#Pathname 时,现在返回参数而不是创建新的 Pathname。这与其他 Kernel 方法更相似,但可能会破坏修改返回值并期望参数不被修改的代码。

profile.rb, Profiler__
  • 已从标准库中删除。自 Ruby 2.0.0 以来一直未维护。

C API 更新

实现改进

纤维
  • 允许通过使用 --with-coroutine= 来选择不同的协程实现,例如

    $ ./configure --with-coroutine=ucontext
    $ ./configure --with-coroutine=copy
  • 将之前的堆栈缓存替换为纤程池缓存。纤程池在单个内存区域中分配多个堆栈。堆栈分配变为 O(log N),纤程创建被摊销为 O(1)。在微基准测试中测量到大约 10 倍的性能提升。 github.com/ruby/ruby/pull/2224

文件
  • File.realpath 现在在许多平台上使用 realpath(3),这可以显著提高性能。[特性 #15797]

哈希
  • 更改小型 Hash 对象的数据结构。[特性 #15602]

监视器
  • Monitor 类是用 C 扩展编写的。[特性 #16255]

线程
  • VM 堆栈内存分配现在与原生线程堆栈合并,提高了线程分配性能并减少了与分配相关的失败。在微基准测试中测量到大约 10 倍的性能提升。

JIT
  • 当优化假设失效时,JIT 代码被重新编译为优化程度较低的代码。

  • Method 内联在方法被认为是纯净时执行。此优化仍处于实验阶段,许多方法尚未被视为纯净。

  • --jit-max-cache 的默认值已从 1,000 更改为 100。

  • --jit-min-calls 的默认值已从 5 更改为 10,000。

RubyVM
  • 自 1.9 左右开始存在的每个调用站点方法缓存已得到改进:缓存命中率从 89% 提高到 94%。参见 github.com/ruby/ruby/pull/2583

RubyVM::InstructionSequence

其他更改