Ruby 2.6.0 Released

We are pleased to announce the release of Ruby 2.6.0.

It introduces a number of new features and performance improvements, most notably:

  • A new JIT compiler.
  • The RubyVM::AbstractSyntaxTree module.

JIT [Experimental]

Ruby 2.6 introduces an initial implementation of a JIT (Just-In-Time) compiler.

The JIT compiler aims to improve the performance of Ruby programs. Unlike traditional JIT compilers which operate in-process, Ruby’s JIT compiler writes out C code to disk and spawns a common C compiler to generate native code. For more details about it, see the MJIT organization by Vladimir Makarov.

In order to enable the JIT compiler, specify --jit on the command line or in the $RUBYOPT environment variable. Specifying --jit-verbose=1 will cause the JIT compiler to print additional information. Read the output of ruby --help or the documentation for other options.

The JIT compiler is supported when Ruby is built by GCC, Clang, or Microsoft VC++, which needs to be available at runtime.

As of Ruby 2.6.0, we have achieved 1.7x faster performance compared to Ruby 2.5 on a CPU-intensive, non-trivial benchmark called Optcarrot. However, it is still experimental and many other memory-intensive workloads like Rails applications might not benefit from it at the moment. For more details, see Ruby 2.6 JIT - Progress and Future.

Stay tuned for the new age of Ruby’s performance.

RubyVM::AbstractSyntaxTree [Experimental]

Ruby 2.6 introduces the RubyVM::AbstractSyntaxTree module. Future compatibility of this module is not guaranteed.

This module has a parse method, which parses the given string as Ruby code and returns the AST (Abstract Syntax Tree) nodes of the code. The parse_file method opens and parses the given file as Ruby code and returns AST nodes.

The RubyVM::AbstractSyntaxTree::Node class is also introduced. You can get source location and children nodes from Node objects. This feature is experimental.

Other Notable New Features

  • Add an alias of Kernel#yield_self named #then. [Feature #14594]

  • Constant names may start with a non-ASCII capital letter. [Feature #13770]

  • Introduce endless ranges. [Feature #12912]

    An endless range, (1..), works as if it has no end. Here are some typical use cases:

    ary[1..]                          # identical to ary[1..-1] without magical -1
    (1..).each {|index| ... }         # enumerates values starting from index 1
    ary.zip(1..) {|elem, index| ... } # ary.each.with_index(1) { ... }
    
  • Add Enumerable#chain and Enumerator#+. [Feature #15144]

  • Add function composition operators << and >> to Proc and Method. [Feature #6284]

    f = proc{|x| x + 2}
    g = proc{|x| x * 3}
    (f << g).call(3) # -> 11; identical to f(g(3))
    (f >> g).call(3) # -> 15; identical to g(f(3))
    
  • Add Binding#source_location. [Feature #14230]

    This method returns the source location of the binding, a 2-element array of __FILE__ and __LINE__. Technically speaking, this is identical to eval("[__FILE__, __LINE__]", binding). However, we are planning to change this behavior so that Kernel#eval ignores binding’s source location [Bug #4352]. As such, it is recommended to use Binding#source_location instead of Kernel#eval.

  • Add an exception: option to Kernel#system which causes it to raise an exception on failure instead of returning false. [Feature #14386]

  • Add a oneshot mode to Coverage. [Feature#15022]

    • This mode checks “whether each line was executed at least once or not”, instead of “how many times each line was executed”. A hook for each line is fired only once, and once it is fired the hook flag will be removed, i.e., it runs with zero overhead.
    • Add oneshot_lines: keyword argument to Coverage.start.
    • Add stop: and clear: keyword arguments to Coverage.result. If clear is true, it clears the counters to zero. If stop is true, it disables coverage measurement.
    • Coverage.line_stub is a simple helper function that creates the “stub” of line coverage from a given source code.
  • Add FileUtils#cp_lr. It works just like cp_r but links instead of copies. [Feature #4189]

Performance improvements

  • Speed up Proc#call by removing the temporary allocation for $SAFE. [Feature #14318]

    We have observed a 1.4x performance improvement in the lc_fizzbuzz benchmark that calls Proc#call numerous times. [Bug #10212]

  • Speed up block.call when block is passed in as a block parameter. [Feature #14330]

    Combined with improvements around block handling introduced in Ruby 2.5, block evaluation now performs 2.6x faster in a micro-benchmark in Ruby 2.6. [Feature #14045]

  • Transient Heap (theap) is introduced. [Bug #14858] [Feature #14989]

    theap is a managed heap for short-living memory objects which are pointed to by specific classes (Array, Hash, Object, and Struct). Making small and short-living Hash objects is 2x faster. With rdoc benchmark, we observed 6-7% performance improvement.

  • Native implementations (arm32, arm64, ppc64le, win32, win64, x86, amd64) of coroutines to improve context switching performance of Fiber significantly. [Feature #14739]

    Fiber.yield and Fiber#resume is about 5x faster on 64-bit Linux. Fiber intensive programs can expect up to 5% improvement overall.

Other notable changes since 2.5

  • $SAFE is now a process global state and it can be set back to 0. [Feature #14250]

  • Passing safe_level to ERB.new is deprecated. trim_mode and eoutvar arguments have been changed to keyword arguments. [Feature #14256]

  • Unicode support is updated to version 11. We have plans to add support for Unicode version 12 and 12.1 in a future TEENY release of Ruby 2.6. This will include support for the new Japanese era.

  • Merge RubyGems 3.0.1. The --ri and --rdoc options have been removed. Please use the --document and --no-document options instead.

  • Bundler is now installed as a default gem.

  • In exception handling blocks, else without rescue now causes a syntax error. [EXPERIMENTAL][Feature #14606]

See NEWS or the commit logs for more details.

With those changes, 6437 files changed, 231471 insertions(+), 98498 deletions(-) since Ruby 2.5.0!

Merry Christmas, Happy Holidays, and enjoy programming with Ruby 2.6!

Known Problem

(This section was added at January 28, 2019.)

Download



OSZAR »