NEWS for Ruby 2.7.0

This document is a list of user visible feature changes made between releases except for bug fixes.

Note that each entry is kept so brief that no reason behind or reference information is supplied with. For a full list of changes with all sufficient information, see the ChangeLog file or Redmine (e.g. https://bugs.ruby-lang.org/issues/$FEATURE_OR_BUG_NUMBER).

Changes since the 2.6.0 release

Language changes

Pattern matching

The spec of keyword arguments is changed towards 3.0

Numbered parameters

proc/lambda without block is deprecated

Other miscellaneous changes

Command line options

Warning option

The -W option has been extended with a following :, to manage categorized warnings. [Feature #16345] [Feature #16420]

See also Warning in Core classes updates.

Core classes updates (outstanding ones only)

Array
New methods
Comparable
Modified method
  • Comparable#clamp now accepts a Range argument. [Feature #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
New method
  • Added Complex#<=>. So 0 <=> 0i will not raise NoMethodError. [Bug #15857]

Dir
Modified methods
  • Dir.glob and Dir.[] no longer allow NUL-separated glob pattern. Use Array instead. [Feature #14643]

Encoding
New encoding
  • Added new encoding CESU-8. [Feature #15931]

Enumerable
New methods
  • Added Enumerable#filter_map. [Feature #15323]

    [1, 2, 3].filter_map {|x| x.odd? ? x.to_s : nil } #=> ["1", "3"]
    
  • Added Enumerable#tally. [Feature #11076]

    ["A", "B", "C", "B", "A"].tally #=> {"A"=>2, "B"=>2, "C"=>1}
    
Enumerator
New methods
  • Added Enumerator.produce to generate an Enumerator from any custom data transformation. [Feature #14781]

    require "date"
    dates = Enumerator.produce(Date.today, &:succ) #=> infinite sequence of dates
    dates.detect(&:tuesday?) #=> next Tuesday
    
  • Added Enumerator::Lazy#eager that generates a non-lazy enumerator from a lazy enumerator. [Feature #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!?"]
    
  • Added Enumerator::Yielder#to_proc so that a Yielder object can be directly passed to another method as a block argument. [Feature #15618]

  • Added Enumerator::Lazy#with_index be lazy Previously, Enumerator::Lazy#with_index was not defined, so it picked up the default implementation from Enumerator, which was not lazy. [Bug #7877]

    ("a"..).lazy.with_index(1) { |it, index| puts "#{index}:#{it}" }.take(3).force
    # => 1:a
    #    2:b
    #    3:c
    
Fiber
New method
File
New method
  • Added File.absolute_path? to check whether a path is absolute or not in a portable way. [Feature #15868]

    File.absolute_path?("/foo")   # => true (on *nix)
    File.absolute_path?("C:/foo") # => true (on Windows)
    File.absolute_path?("foo")    # => false
    
Modified method
  • File.extname now returns a dot string for names ending with a dot on non-Windows platforms. [Bug #15267]

    File.extname("foo.") #=> "."
    
FrozenError
New method
GC
New method
  • Added GC.compact method for compacting the heap. This function compacts live objects in the heap so that fewer pages may be used, and the heap may be more CoW (copy-on-write) friendly. [Feature #15626]

    Details on the algorithm and caveats can be found here: bugs.ruby-lang.org/issues/15626

IO
New method
Integer
Modified method
  • Integer#[] now supports range operations. [Feature #8842]

    0b01001101[2, 4]  #=> 0b0011
    0b01001100[2..5]  #=> 0b0011
    0b01001100[2...6] #=> 0b0011
    #   ^^^^
    
Method
Modified method
Module
New methods
  • Added Module#const_source_location to retrieve the location where a constant is defined. [Feature #10771]

  • Added Module#ruby2_keywords for marking a method as passing keyword arguments through a regular argument splat, useful when delegating all arguments to another method in a way that can be backwards compatible with older Ruby versions. [Bug #16154]

Modified methods
NilClass / TrueClass / FalseClass
Modified methods
ObjectSpace::WeakMap
Modified method
Proc
New method
  • Added Proc#ruby2_keywords for marking the proc as passing keyword arguments through a regular argument splat, useful when delegating all arguments to another method or proc in a way that can be backwards compatible with older Ruby versions. [Feature #16404]

Range
New method
Modified method
RubyVM
Removed method
  • RubyVM.resolve_feature_path moved to $LOAD_PATH.resolve_feature_path. [Feature #15903] [Feature #15230]

String
Unicode
  • Update Unicode version and Emoji version from 11.0.0 to 12.0.0. [Feature #15321]

  • Update Unicode version to 12.1.0, adding support for U+32FF SQUARE ERA NAME REIWA. [Feature #15195]

  • Update Unicode Emoji version to 12.1. [Feature #16272]

Symbol
New methods
Time
New methods
Modified method
UnboundMethod
New method
  • Added UnboundMethod#bind_call method. [Feature #15955]

    umethod.bind_call(obj, ...) is semantically equivalent to umethod.bind(obj).call(...). This idiom is used in some libraries to call a method that is overridden. The added method does the same without allocation of an intermediate Method object.

    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
New methods
  • Added Warning.[] and Warning.[]= to manage emitting/suppressing some categories of warnings. [Feature #16345] [Feature #16420]

$LOAD_PATH
New method
  • Added $LOAD_PATH.resolve_feature_path. [Feature #15903] [Feature #15230]

Stdlib updates (outstanding ones only)

Bundler
CGI
CSV
Date
  • Date.jisx0301, Date#jisx0301, and Date.parse support the new Japanese era. [Feature #15742]

Delegator
  • Object#DelegateClass accepts a block and module_evals it in the context of the returned class, similar to Class.new and Struct.new.

ERB
  • Prohibit marshaling ERB instance.

IRB
  • Introduce syntax highlighting inspired by the Pry gem to Binding#irb source lines, REPL input, and inspect output of some core-class objects.

  • Introduce multiline editing mode provided by Reline.

  • Show documentation when completion.

  • Enable auto indent and save/load history by default.

JSON
  • Upgrade to 2.3.0.

Net::FTP
  • Add Net::FTP#features to check available features, and Net::FTP#option to enable/disable each of them. [Feature #15964]

Net::HTTP
  • Add ipaddr optional parameter to Net::HTTP#start to replace the address for the TCP/IP connection. [Feature #5180]

Net::IMAP
  • Add Server Name Indication (SNI) support. [Feature #15594]

open-uri
  • Warn open-uri’s “open” method at Kernel. Use URI.open instead. [Misc #15893]

  • The default charset of “text/*” media type is UTF-8 instead of ISO-8859-1. [Bug #15933]

OptionParser
  • Now show “Did you mean?” for unknown options. [Feature #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!
    

    example:

    $ 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 now delegates 3 arguments to Dir.glob to accept base keyword. [Feature #14405]

Racc
  • Merge 1.4.15 from upstream repository and added cli of racc.

Reline
  • New stdlib that is compatible with the readline stdlib but is implemented in pure Ruby. It also provides a multiline editing mode.

REXML
RSS
RubyGems
StringScanner

Compatibility issues (excluding feature bug fixes)

Proc
  • The Proc#to_s format was changed. [Feature #16101]

Range
  • Range#minmax used to iterate on the range to determine the maximum. It now uses the same algorithm as Range#max. In rare cases (e.g. ranges of Floats or Strings), this may yield different results. [Bug #15807]

Stdlib compatibility issues (excluding feature bug fixes)

pathname
  • Kernel#Pathname when called with a Pathname argument now returns the argument instead of creating a new Pathname. This is more similar to other Kernel methods, but can break code that modifies the return value and expects the argument not to be modified.

profile.rb, Profiler__
  • Removed from standard library. It was unmaintained since Ruby 2.0.0.

C API updates

Implementation improvements

Fiber
  • Allow selecting different coroutine implementations by using --with-coroutine=, e.g.

    $ ./configure --with-coroutine=ucontext
    $ ./configure --with-coroutine=copy
  • Replace previous stack cache with fiber pool cache. The fiber pool allocates many stacks in a single memory region. Stack allocation becomes O(log N) and fiber creation is amortized O(1). Around 10x performance improvement was measured in micro-benchmarks. github.com/ruby/ruby/pull/2224

File
  • File.realpath now uses realpath(3) on many platforms, which can significantly improve performance. [Feature #15797]

Hash
  • Change data structure of small Hash objects. [Feature #15602]

Monitor
  • Monitor class is written in C-extension. [Feature #16255]

Thread
  • VM stack memory allocation is now combined with native thread stack, improving thread allocation performance and reducing allocation related failures. Around 10x performance improvement was measured in micro-benchmarks.

JIT
  • JIT-ed code is recompiled to less-optimized code when an optimization assumption is invalidated.

  • Method inlining is performed when a method is considered as pure. This optimization is still experimental and many methods are NOT considered as pure yet.

  • The default value of --jit-max-cache is changed from 1,000 to 100.

  • The default value of --jit-min-calls is changed from 5 to 10,000.

RubyVM
  • Per-call-site method cache, which has been there since around 1.9, was improved: cache hit rate raised from 89% to 94%. See github.com/ruby/ruby/pull/2583

RubyVM::InstructionSequence

Miscellaneous changes