ruby/NEWS.md

19 KiB
Исходник Ответственный История

NEWS for Ruby 3.1.0

This document is a list of user-visible feature changes since the 3.0.0 release, except for bug fixes.

Note that each entry is kept to a minimum, see links for details.

Language changes

  • The block argument can now be anonymous if the block will only be passed to another method. [Feature #11256]

    def foo(&)
      bar(&)
    end
    
  • Pin operator now takes an expression. [Feature #17411]

    Prime.each_cons(2).lazy.find_all{_1 in [n, ^(n + 2)]}.take(3).to_a
    #=> [[3, 5], [5, 7], [11, 13]]
    
  • Pin operator now supports instance, class, and global variables. [Feature #17724]

    @n = 5
    Prime.each_cons(2).lazy.find{_1 in [n, ^@n]}
    #=> [3, 5]
    
  • One-line pattern matching is no longer experimental.

  • Parentheses can be omitted in one-line pattern matching. [Feature #16182]

    [0, 1] => _, x
    {y: 2} => y:
    x #=> 1
    y #=> 2
    
  • Multiple assignment evaluation order has been made consistent with single assignment evaluation order. With single assignment, Ruby uses a left-to-right evaluation order. With this code:

    foo[0] = bar
    

    The following evaluation order is used:

    1. foo
    2. bar
    3. []= called on the result of foo

    In Ruby before 3.1.0, multiple assignment did not follow this evaluation order. With this code:

    foo[0], bar.baz = a, b
    

    Versions of Ruby before 3.1.0 would evaluate in the following order

    1. a
    2. b
    3. foo
    4. []= called on the result of foo
    5. bar
    6. baz= called on the result of bar

    Starting in Ruby 3.1.0, the evaluation order is now consistent with single assignment, with the left-hand side being evaluated before the right-hand side:

    1. foo
    2. bar
    3. a
    4. b
    5. []= called on the result of foo
    6. baz= called on the result of bar

    [Bug #4443]

  • Values in Hash literals and keyword arguments can be omitted. [Feature #14579]

    For example,

    • {x:, y:} is a syntax sugar of {x: x, y: y}.
    • foo(x:, y:) is a syntax sugar of foo(x: x, y: y).

    Constant names, local variable names, and method names are allowed as key names. Note that a reserved word is considered as a local variable or method name even if it's a pseudo variable name such as self.

  • Non main-Ractors can get instance variables (ivars) of classes/modules if ivars refer to shareable objects. [Feature #17592]

  • A command syntax is allowed in endless method definitions, i.e., you can now write def foo = puts "Hello". Note that private def foo = puts "Hello" does not parse. [Feature #17398]

Command line options

  • --disable-gems is now explicitly declared as "just for debugging". Never use it in any real-world codebase. [Feature #17684]

Core classes updates

Note: We're only listing outstanding class updates.

  • Array

  • Class

    • Class#descendants, which returns an array of classes directly or indirectly inheriting from the receiver, not including the receiver or singleton classes. [Feature #14394]

      class A; end
      class B < A; end
      class C < B; end
      A.descendants    #=> [B, C]
      B.descendants    #=> [C]
      C.descendants    #=> []
      
    • Class#subclasses, which returns an array of classes directly inheriting from the receiver, not including singleton classes. [Feature #18273]

      class A; end
      class B < A; end
      class C < B; end
      class D < A; end
      A.subclasses    #=> [D, B]
      B.subclasses    #=> [C]
      C.subclasses    #=> []
      
  • Enumerable

    • Enumerable#compact is added. [Feature #17312]

    • Enumerable#tally now accepts an optional hash to count. [Feature #17744]

    • Enumerable#each_cons and each_slice to return a receiver. [GH-1509]

      [1, 2, 3].each_cons(2){}
      # 3.0 => nil
      # 3.1 => [1, 2, 3]
      
      [1, 2, 3].each_slice(2){}
      # 3.0 => nil
      # 3.1 => [1, 2, 3]
      
  • Enumerator::Lazy

  • File

    • File.dirname now accepts an optional argument for the level to strip path components. [Feature #12194]
  • GC

    • "GC.measure_total_time = true" enables the measurement of GC. Measurement can introduce overhead. It is enabled by default. GC.measure_total_time returns the current setting. GC.stat[:time] or GC.stat(:time) returns measured time in milli-seconds.

    • GC.total_time returns measured time in nano-seconds.

  • Integer

  • Kernel

    • Kernel#load now accepts a module as the second argument, and will load the file using the given module as the top-level module. [Feature #6210]
  • Marshal

    • Marshal.load now accepts a freeze: true option. All returned objects are frozen except for Class and Module instances. Strings are deduplicated. [Feature #18148]
  • MatchData

  • Method/UnboundMethod

    • Method#public?, Method#private?, Method#protected?, UnboundMethod#public?, UnboundMethod#private?, UnboundMethod#protected? have been added. [Feature #11689]
  • Module

    • Module#prepend now modifies the ancestor chain if the receiver already includes the argument. Module#prepend still does not modify the ancestor chain if the receiver has already prepended the argument. [Bug #17423]

    • Module#private, #public, #protected, and #module_function will now return their arguments. If a single argument is given, it is returned. If no arguments are given, nil is returned. If multiple arguments are given, they are returned as an array. [Feature #12495]

  • Process

    • Process._fork is added. This is a core method for fork(2). Do not call this method directly; it is called by existing fork methods: Kernel.#fork, Process.fork, and IO.popen("-"). Application monitoring libraries can overwrite this method to hook fork events. [Feature #17795]
  • Struct

    • Passing only keyword arguments to Struct#initialize is warned. You need to use a Hash literal to set a Hash to a first member. [Feature #16806]

    • StructClass#keyword_init? is added [Feature #18008]

  • String

    • Update Unicode version to 13.0.0 [Feature #17750] and Emoji version to 13.0 [Feature #18029]

    • String#unpack and String#unpack1 now accept an offset: keyword argument to start the unpacking after an arbitrary number of bytes have been skipped. If offset is outside of the string bounds ArgumentError is raised. [Feature #18254]

  • Queue

    • Queue#initialize now accepts an Enumerable of initial values. [Feature #17327]
  • Thread

  • Thread::Backtrace

    • Thread::Backtrace.limit, which returns the value to limit backtrace length set by --backtrace-limit command line option, is added. [Feature #17479]
  • Time

    • Time.new now accepts optional in: keyword argument for the timezone, as well as Time.at and Time.now, so that is now you can omit minor arguments to Time.new. [Feature #17485]

    • Time#strftime supports RFC 3339 UTC for unknown offset local time, -0000, as %-z. [Feature #17544]

  • TracePoint

    • TracePoint.allow_reenter is added to allow reenter while TracePoint callback. [Feature #15912]
  • $LOAD_PATH

  • Fiber Scheduler

    • Add support for Addrinfo.getaddrinfo using address_resolve hook. [Feature #17370]

    • Introduce non-blocking Timeout.timeout using timeout_after hook. [Feature #17470]

    • Introduce new scheduler hooks io_read and io_write along with a low level IO::Buffer for zero-copy read/write. [Feature #18020]

    • IO hooks io_wait, io_read, io_write, receive the original IO object where possible. [Bug #18003]

    • Make Monitor fiber-safe. [Bug #17827]

    • Replace copy coroutine with pthread implementation. [Feature #18015]

  • Refinement

    • New class which represents a module created by Module#refine. include and prepend are deprecated, and import_methods is added instead. [Bug #17429]

Stdlib updates

  • The following default gem are updated.

    • RubyGems 3.3.0.dev
    • base64 0.1.1
    • benchmark 0.2.0
    • bigdecimal 3.1.0.dev
    • bundler 2.3.0.dev
    • cgi 0.3.1
    • csv 3.2.1
    • date 3.2.2
    • did_you_mean 1.6.0.pre.alpha
    • digest 3.1.0.pre3
    • drb 2.1.0
    • erb 2.2.3
    • error_highlight 0.2.0
    • etc 1.3.0
    • fcntl 1.0.1
    • fiddle 1.1.0
    • fileutils 1.6.0
    • find 0.1.1
    • io-console 0.5.9
    • io-wait 0.2.1
    • ipaddr 1.2.3
    • irb 1.3.8.pre.11
    • json 2.6.1
    • logger 1.4.4
    • net-http 0.2.0
    • net-protocol 0.1.2
    • nkf 0.1.1
    • open-uri 0.2.0
    • openssl 3.0.0.pre
    • optparse 0.2.0
    • ostruct 0.5.2
    • pathname 0.2.0
    • pp 0.2.1
    • prettyprint 0.1.1
    • psych 4.0.2
    • racc 1.6.0
    • rdoc 6.3.2
    • readline-ext 0.1.3
    • reline 0.2.8.pre.11
    • resolv 0.2.1
    • rinda 0.1.1
    • ruby2_keywords 0.0.5
    • securerandom 0.1.1
    • set 1.0.2
    • stringio 3.0.1
    • strscan 3.0.1
    • tempfile 0.1.2
    • time 0.2.0
    • timeout 0.2.0
    • tmpdir 0.1.2
    • un 0.2.0
    • uri 0.11.0
    • yaml 0.2.0
    • zlib 2.1.1
  • The following bundled gems are updated.

    • minitest 5.15.0
    • power_assert 2.0.1
    • rake 13.0.6
    • test-unit 3.5.2
    • rexml 3.2.5
    • rbs 1.8.1
    • typeprof 0.20.4
  • The following default gems are now bundled gems.

    • net-ftp 0.1.3
    • net-imap 0.2.2
    • net-pop 0.1.1
    • net-smtp 0.3.1
    • matrix 0.4.2
    • prime 0.1.2
    • debug 1.4.0
  • Coverage measurement now supports suspension. You can use Coverage.suspend to stop the measurement temporarily, and Coverage.resume to restart it. See [Feature #18176] in detail.

  • Random::Formatter is moved to random/formatter.rb, so that you can use Random#hex, Random#base64, and so on without SecureRandom. [Feature #18190]

Compatibility issues

Note: Excluding feature bug fixes.

  • rb_io_wait_readable, rb_io_wait_writable and rb_wait_for_single_fd are deprecated in favour of rb_io_maybe_wait_readable, rb_io_maybe_wait_writable and rb_io_maybe_wait respectively. rb_thread_wait_fd and rb_thread_fd_writable are deprecated. [Bug #18003]

Stdlib compatibility issues

  • ERB#initialize warns safe_level and later arguments even without -w. [Feature #14256]

  • lib/debug.rb is replaced with debug.gem

  • Kernel#pp in lib/pp.rb uses the width of IO#winsize by default. This means that the output width is automatically changed depending on your terminal size. [Feature #12913]

C API updates

  • Documented. [GH-4815]

  • rb_gc_force_recycle is deprecated and has been changed to a no-op. [Feature #18290]

Implementation improvements

  • instance_eval and instance_exec now only allocate a singleton class when required, avoiding extra objects and improving performance. [GH-5146]

  • The performance of Struct accessors is improved. [GH-5131]

  • mandatory_only? builtin special form to improve performance on builtin methods. [GH-5112]

  • Experimental feature Variable Width Allocation in the garbage collector. This feature is turned off by default and can be enabled by compiling Ruby with flag USE_RVARGC=1 set. [Feature #18045] [Feature #18239]

JIT

  • Rename Ruby 3.0's --jit to --mjit, and alias --jit to --yjit on non-Windows x86-64 platforms and to --mjit on others.

MJIT

  • The default --mjit-max-cache is changed from 100 to 10000.

  • JIT-ed code is no longer cancelled when a TracePoint for class events is enabled.

  • The JIT compiler no longer skips compilation of methods longer than 1000 instructions.

  • --mjit-verbose and --mjit-warning output "JIT cancel" when JIT-ed code is disabled because TracePoint or GC.compact is used.

YJIT: New experimental in-process JIT compiler

New JIT compiler available as an experimental feature. [Feature #18229]

See this blog post introducing the project.

  • Disabled by default, use --yjit command-line option to enable YJIT.

  • Performance improvements on most real-world software, up to 22% on railsbench, 39% on liquid-render.

  • Fast warm-up times.

  • Limited to macOS & Linux on x86-64 platforms for now.

Static analysis

RBS

  • rbs collection has been introduced to manage gems RBSs.
  • Many signatures for built-in and standard libraries have been added/updated.
  • It includes many bug fixes and performance improvements too.

See the CHANGELOG.md for more information.

TypeProf

Debugger

  • A new debugger debug.gem is bundled. debug.gem is a fast debugger implementation, and it provides many features like remote debugging, colorful REPL, IDE (VSCode) integration, and more. It replaces lib/debug.rb standard library.

  • rdbg command is also installed into bin/ directory to start and control debugging execution.

error_highlight

A built-in gem called error_highlight has been introduced. It shows fine-grained error locations in the backtrace.

Example: title = json[:article][:title]

If json is nil, it shows:

$ ruby test.rb
test.rb:2:in `<main>': undefined method `[]' for nil:NilClass (NoMethodError)

title = json[:article][:title]
            ^^^^^^^^^^

If json[:article] returns nil, it shows:

$ ruby test.rb
test.rb:2:in `<main>': undefined method `[]' for nil:NilClass (NoMethodError)

title = json[:article][:title]
                      ^^^^^^^^

This feature is enabled by default. You can disable it by using a command-line option --disable-error_highlight. See the repository in detail.

Miscellaneous changes

  • lib/objspace/trace.rb is added, which is a tool for tracing the object allocation. Just by requiring this file, tracing is started immediately. Just by Kernel#p, you can investigate where an object was created. Note that just requiring this file brings a large performance overhead. This is only for debugging purposes. Do not use this in production. [Feature #17762]

  • Now exceptions raised in finalizers will be printed to STDERR, unless $VERBOSE is nil. [Feature #17798]

  • ruby -run -e httpd displays URLs to access. [Feature #17847]

  • Add ruby -run -e colorize to colorize Ruby code using IRB::Color.colorize_code.