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
修改后的方法
  • 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
新方法
Dir
修改后的方法
  • Dir.globDir.[] 不再允许以 NUL 分隔的 glob 模式。请改用 Array。[功能 #14643]

编码
新编码
  • 添加了新编码 CESU-8。[功能 #15931]

Enumerable
新方法
  • 添加了 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
新方法
  • 添加了 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 中获取默认实现,而该默认实现不是惰性的。[错误 #7877]

    ("a"..).lazy.with_index(1) { |it, index| puts "#{index}:#{it}" }.take(3).force
    # => 1:a
    #    2:b
    #    3:c
    
Fiber
新方法
  • 添加了 Fiber#raise,它的行为类似于 Fiber#resume,但在恢复的纤程上引发异常。[功能 #10344]

文件
新方法
  • 添加了 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 平台以点结尾的名称返回一个点字符串。[错误 #15267]

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

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

IO
新方法
Integer
修改后的方法
  • Integer#[] 现在支持范围操作。[功能 #8842]

    0b01001101[2, 4]  #=> 0b0011
    0b01001100[2..5]  #=> 0b0011
    0b01001100[2...6] #=> 0b0011
    #   ^^^^
    
Method
修改后的方法
Module
新方法
  • 添加了 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]

String
Unicode
  • 将 Unicode 版本和 Emoji 版本从 11.0.0 更新到 12.0.0。[功能 #15321]

  • 将 Unicode 版本更新到 12.1.0,添加了对 U+32FF SQUARE ERA NAME REIWA 的支持。[功能 #15195]

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

Symbol
新方法
Time
新方法
修改后的方法
UnboundMethod
新方法
  • 添加了 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.[]Warning.[]= 方法,用于管理发出/抑制某些类别的警告。[功能 #16345] [功能 #16420]

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

Stdlib 更新(仅限未完成的更新)

Bundler
CGI
CSV
Date
Delegator
ERB
  • 禁止封送 ERB 实例。

IRB
  • 引入了受 Pry gem 启发的语法高亮显示,用于 Binding#irb 源行、REPL 输入和某些核心类对象的 inspect 输出。

  • 引入了由 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
  • Kernel 中警告 open-uri 的 “open” 方法。请改用 URI.open。[其他 #15893]

  • “text/*” 媒体类型的默认字符集为 UTF-8 而不是 ISO-8859-1。[Bug #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
Racc
  • 从上游存储库合并 1.4.15 并添加了 racc 的 cli。

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

REXML
RSS
RubyGems
StringScanner

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

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

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

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

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

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

C API 更新

实现改进

Fiber
  • 允许使用 --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
  • 更改小型 Hash 对象的数据结构。[特性 #15602]

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

线程
  • 虚拟机栈内存分配现在与原生线程栈相结合,提高了线程分配性能并减少了与分配相关的失败。在微基准测试中测得大约 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

杂项更改