* 2022-01-18 [ci skip]
[ruby-80x24.org.git] / doc / NEWS-2.7.0
blob7607a473de72f33b4564e0839b653805cf239754
1 # -*- rdoc -*-
3 = NEWS for Ruby 2.7.0
5 This document is a list of user visible feature changes made between
6 releases except for bug fixes.
8 Note that each entry is kept so brief that no reason behind or reference
9 information is supplied with.  For a full list of changes with all
10 sufficient information, see the ChangeLog file or Redmine
11 (e.g. <tt>https://bugs.ruby-lang.org/issues/$FEATURE_OR_BUG_NUMBER</tt>).
13 == Changes since the 2.6.0 release
15 === Language changes
17 ==== Pattern matching
19 * Pattern matching is introduced as an experimental feature. [Feature #14912]
21     case [0, [1, 2, 3]]
22     in [a, [b, *c]]
23       p a #=> 0
24       p b #=> 1
25       p c #=> [2, 3]
26     end
28     case {a: 0, b: 1}
29     in {a: 0, x: 1}
30       :unreachable
31     in {a: 0, b: var}
32       p var #=> 1
33     end
35     case -1
36     in 0 then :unreachable
37     in 1 then :unreachable
38     end #=> NoMatchingPatternError
40     json = <<END
41     {
42       "name": "Alice",
43       "age": 30,
44       "children": [{ "name": "Bob", "age": 2 }]
45     }
46     END
48     JSON.parse(json, symbolize_names: true) in {name: "Alice", children: [{name: name, age: age}]}
50     p name #=> "Bob"
51     p age  #=> 2
53     JSON.parse(json, symbolize_names: true) in {name: "Alice", children: [{name: "Charlie", age: age}]}
54     #=> NoMatchingPatternError
56 * See the following slides for more details:
57   * https://speakerdeck.com/k_tsj/pattern-matching-new-feature-in-ruby-2-dot-7
58   * Note that the slides are slightly obsolete.
60 * The warning against pattern matching can be suppressed with
61   {-W:no-experimental option}[#label-Warning+option].
63 ==== The spec of keyword arguments is changed towards 3.0
65 * Automatic conversion of keyword arguments and positional arguments is
66   deprecated, and conversion will be removed in Ruby 3.  [Feature #14183]
68   * When a method call passes a Hash at the last argument, and when it
69     passes no keywords, and when the called method accepts keywords,
70     a warning is emitted.  To continue treating the hash as keywords,
71     add a double splat operator to avoid the warning and ensure
72     correct behavior in Ruby 3.
74       def foo(key: 42); end; foo({key: 42})   # warned
75       def foo(**kw);    end; foo({key: 42})   # warned
76       def foo(key: 42); end; foo(**{key: 42}) # OK
77       def foo(**kw);    end; foo(**{key: 42}) # OK
79   * When a method call passes keywords to a method that accepts keywords,
80     but it does not pass enough required positional arguments, the
81     keywords are treated as a final required positional argument, and a
82     warning is emitted.  Pass the argument as a hash instead of keywords
83     to avoid the warning and ensure correct behavior in Ruby 3.
85       def foo(h, **kw); end; foo(key: 42)      # warned
86       def foo(h, key: 42); end; foo(key: 42)   # warned
87       def foo(h, **kw); end; foo({key: 42})    # OK
88       def foo(h, key: 42); end; foo({key: 42}) # OK
90   * When a method accepts specific keywords but not a keyword splat, and
91     a hash or keywords splat is passed to the method that includes both
92     Symbol and non-Symbol keys, the hash will continue to be split, and
93     a warning will be emitted.  You will need to update the calling code
94     to pass separate hashes to ensure correct behavior in Ruby 3.
96       def foo(h={}, key: 42); end; foo("key" => 43, key: 42)   # warned
97       def foo(h={}, key: 42); end; foo({"key" => 43, key: 42}) # warned
98       def foo(h={}, key: 42); end; foo({"key" => 43}, key: 42) # OK
100   * If a method does not accept keywords, and is called with keywords,
101     the keywords are still treated as a positional hash, with no warning.
102     This behavior will continue to work in Ruby 3.
104       def foo(opt={});  end; foo( key: 42 )   # OK
106 * Non-symbols are allowed as keyword argument keys if the method accepts
107   arbitrary keywords. [Feature #14183]
109   * Non-Symbol keys in a keyword arguments hash were prohibited in 2.6.0,
110     but are now allowed again.  [Bug #15658]
112       def foo(**kw); p kw; end; foo("str" => 1) #=> {"str"=>1}
114 * <code>**nil</code> is allowed in method definitions to explicitly mark
115   that the method accepts no keywords. Calling such a method with keywords
116   will result in an ArgumentError. [Feature #14183]
118     def foo(h, **nil); end; foo(key: 1)       # ArgumentError
119     def foo(h, **nil); end; foo(**{key: 1})   # ArgumentError
120     def foo(h, **nil); end; foo("str" => 1)   # ArgumentError
121     def foo(h, **nil); end; foo({key: 1})     # OK
122     def foo(h, **nil); end; foo({"str" => 1}) # OK
124 * Passing an empty keyword splat to a method that does not accept keywords
125   no longer passes an empty hash, unless the empty hash is necessary for
126   a required parameter, in which case a warning will be emitted.  Remove
127   the double splat to continue passing a positional hash.  [Feature #14183]
129     h = {}; def foo(*a) a end; foo(**h) # []
130     h = {}; def foo(a) a end; foo(**h)  # {} and warning
131     h = {}; def foo(*a) a end; foo(h)   # [{}]
132     h = {}; def foo(a) a end; foo(h)    # {}
134 * Above warnings can be suppressed also with {-W:no-deprecated option}[#label-Warning+option].
136 ==== Numbered parameters
138 * Numbered parameters as default block parameters are introduced. [Feature #4475]
140     [1, 2, 10].map { _1.to_s(16) }    #=> ["1", "2", "a"]
141     [[1, 2], [3, 4]].map { _1 + _2 }  #=> [3, 7]
143   You can still define a local variable named +_1+ and so on,
144   and that is honored when present, but renders a warning.
146     _1 = 0            #=> warning: `_1' is reserved for numbered parameter; consider another name
147     [1].each { p _1 } # prints 0 instead of 1
149 ==== proc/lambda without block is deprecated
151 * Proc.new and Kernel#proc with no block in a method called with a block will
152   now display a warning.
154     def foo
155       proc
156     end
157     foo { puts "Hello" } #=> warning: Capturing the given block using Kernel#proc is deprecated; use `&block` instead
159   This warning can be suppressed with {-W:no-deprecated option}[#label-Warning+option].
161 * Kernel#lambda with no block in a method called with a block raises an exception.
163     def bar
164       lambda
165     end
166     bar { puts "Hello" } #=> tried to create Proc object without a block (ArgumentError)
168 ==== Other miscellaneous changes
170 * A beginless range is experimentally introduced.  It might be useful
171   in +case+, new call-sequence of the <code>Comparable#clamp</code>,
172   constants and DSLs.  [Feature #14799]
174      ary[..3]  # identical to ary[0..3]
176      case RUBY_VERSION
177      when ..."2.4" then puts "EOL"
178      # ...
179      end
181      age.clamp(..100)
183      where(sales: ..100)
185 * Setting <code>$;</code> to a non-nil value will now display a warning. [Feature #14240]
186   This includes the usage in String#split.
187   This warning can be suppressed with {-W:no-deprecated option}[#label-Warning+option].
189 * Setting <code>$,</code> to a non-nil value will now display a warning. [Feature #14240]
190   This includes the usage in Array#join.
191   This warning can be suppressed with {-W:no-deprecated option}[#label-Warning+option].
193 * Quoted here-document identifiers must end within the same line.
195      <<"EOS
196      " # This had been warned since 2.4; Now it raises a SyntaxError
197      EOS
199 * The flip-flop syntax deprecation is reverted. [Feature #5400]
201 * Comment lines can be placed between fluent dot now.
203     foo
204       # .bar
205       .baz # => foo.baz
207 * Calling a private method with a literal +self+ as the receiver
208   is now allowed. [Feature #11297] [Feature #16123]
210 * Modifier rescue now operates the same for multiple assignment as single
211   assignment. [Bug #8279]
213     a, b = raise rescue [1, 2]
214     # Previously parsed as: (a, b = raise) rescue [1, 2]
215     # Now parsed as:         a, b = (raise rescue [1, 2])
217 * +yield+ in singleton class syntax will now display a warning. This behavior
218   will soon be deprecated. [Feature #15575].
220    def foo
221      class << Object.new
222        yield #=> warning: `yield' in class syntax will not be supported from Ruby 3.0. [Feature #15575]
223      end
224    end
225    foo { p :ok }
227   This warning can be suppressed with {-W:no-deprecated option}[#label-Warning+option].
229 * Argument forwarding by <code>(...)</code> is introduced. [Feature #16253]
231     def foo(...)
232       bar(...)
233     end
235   All arguments to +foo+ are forwarded to +bar+, including keyword and
236   block arguments.
237   Note that the parentheses are mandatory.  <code>bar ...</code> is parsed
238   as an endless range.
240 * Access and setting of <code>$SAFE</code> will now always display a warning.
241   <code>$SAFE</code> will become a normal global variable in Ruby 3.0.  [Feature #16131]
243 * <code>Object#{taint,untaint,trust,untrust}</code> and related functions in the C-API
244   no longer have an effect (all objects are always considered untainted), and will now
245   display a warning in verbose mode. This warning will be disabled even in non-verbose mode in
246   Ruby 3.0, and the methods and C functions will be removed in Ruby 3.2. [Feature #16131]
248 * Refinements take place at Object#method and Module#instance_method. [Feature #15373]
250 === Command line options
252 ==== Warning option
254 The +-W+ option has been extended with a following +:+, to manage categorized
255 warnings.  [Feature #16345] [Feature #16420]
257 * To suppress deprecation warnings:
259     $ ruby -e '$; = ""'
260     -e:1: warning: `$;' is deprecated
262     $ ruby -W:no-deprecated -e '$; = //'
264 * It works with the +RUBYOPT+ environment variable:
266     $ RUBYOPT=-W:no-deprecated ruby -e '$; = //'
268 * To suppress experimental feature warnings:
270     $ ruby -e '0 in a'
271     -e:1: warning: Pattern matching is experimental, and the behavior may change in future versions of Ruby!
273     $ ruby -W:no-experimental -e '0 in a'
275 * To suppress both by using +RUBYOPT+, set space separated values:
277     $ RUBYOPT='-W:no-deprecated -W:no-experimental' ruby -e '($; = "") in a'
279 See also Warning in {Core classes updates}[#label-Core+classes+updates+-28outstanding+ones+only-29].
281 === Core classes updates (outstanding ones only)
283 [Array]
285   [New methods]
287     * Added Array#intersection. [Feature #16155]
289     * Added Array#minmax, with a faster implementation than Enumerable#minmax. [Bug #15929]
291 [Comparable]
293   [Modified method]
295     * Comparable#clamp now accepts a Range argument. [Feature #14784]
297         -1.clamp(0..2) #=> 0
298          1.clamp(0..2) #=> 1
299          3.clamp(0..2) #=> 2
300         # With beginless and endless ranges:
301         -1.clamp(0..)  #=> 0
302          3.clamp(..2)  #=> 2
305 [Complex]
307   [New method]
309     * Added Complex#<=>.
310       So <code>0 <=> 0i</code> will not raise NoMethodError. [Bug #15857]
312 [Dir]
314   [Modified methods]
316     * Dir.glob and Dir.[] no longer allow NUL-separated glob pattern.
317       Use Array instead.  [Feature #14643]
319 [Encoding]
321   [New encoding]
323     * Added new encoding CESU-8. [Feature #15931]
325 [Enumerable]
327   [New methods]
329     * Added Enumerable#filter_map.  [Feature #15323]
331         [1, 2, 3].filter_map {|x| x.odd? ? x.to_s : nil } #=> ["1", "3"]
333     * Added Enumerable#tally.  [Feature #11076]
335         ["A", "B", "C", "B", "A"].tally #=> {"A"=>2, "B"=>2, "C"=>1}
337 [Enumerator]
339   [New methods]
341     * Added Enumerator.produce to generate an Enumerator from any custom
342       data transformation.  [Feature #14781]
344         require "date"
345         dates = Enumerator.produce(Date.today, &:succ) #=> infinite sequence of dates
346         dates.detect(&:tuesday?) #=> next Tuesday
348     * Added Enumerator::Lazy#eager that generates a non-lazy enumerator
349       from a lazy enumerator.  [Feature #15901]
351         a = %w(foo bar baz)
352         e = a.lazy.map {|x| x.upcase }.map {|x| x + "!" }.eager
353         p e.class               #=> Enumerator
354         p e.map {|x| x + "?" }  #=> ["FOO!?", "BAR!?", "BAZ!?"]
356     * Added Enumerator::Yielder#to_proc so that a Yielder object
357       can be directly passed to another method as a block
358       argument.  [Feature #15618]
360     * Added Enumerator::Lazy#with_index be lazy
361       Previously, Enumerator::Lazy#with_index was not defined, so it
362       picked up the default implementation from Enumerator, which was
363       not lazy.  [Bug #7877]
365         ("a"..).lazy.with_index(1) { |it, index| puts "#{index}:#{it}" }.take(3).force
366         # => 1:a
367         #    2:b
368         #    3:c
370 [Fiber]
372   [New method]
374     * Added Fiber#raise that behaves like Fiber#resume but raises an
375       exception on the resumed fiber.  [Feature #10344]
377 [File]
379   [New method]
381     * Added File.absolute_path? to check whether a path is absolute or
382       not in a portable way. [Feature #15868]
384         File.absolute_path?("/foo")   # => true (on *nix)
385         File.absolute_path?("C:/foo") # => true (on Windows)
386         File.absolute_path?("foo")    # => false
388   [Modified method]
390     * File.extname now returns a dot string for names ending with a dot on
391       non-Windows platforms.  [Bug #15267]
393           File.extname("foo.") #=> "."
395 [FrozenError]
397   [New method]
399     * Added FrozenError#receiver to return the frozen object on which
400       modification was attempted.  To set this object when raising
401       FrozenError in Ruby code, FrozenError.new accepts a +:receiver+
402       option.  [Feature #15751]
404 [GC]
406   [New method]
408     * Added GC.compact method for compacting the heap.
409       This function compacts live objects in the heap so that fewer pages may
410       be used, and the heap may be more CoW (copy-on-write) friendly. [Feature #15626]
412       Details on the algorithm and caveats can be found here:
413       https://bugs.ruby-lang.org/issues/15626
415 [IO]
417   [New method]
419     * Added IO#set_encoding_by_bom to check the BOM and set the external
420       encoding.  [Bug #15210]
422 [Integer]
424   [Modified method]
426     * Integer#[] now supports range operations.  [Feature #8842]
428          0b01001101[2, 4]  #=> 0b0011
429          0b01001100[2..5]  #=> 0b0011
430          0b01001100[2...6] #=> 0b0011
431          #   ^^^^
433 [Method]
435   [Modified method]
437     * Method#inspect shows more information. [Feature #14145]
439 [Module]
441   [New methods]
443     * Added Module#const_source_location to retrieve the location where a
444       constant is defined.  [Feature #10771]
446     * Added Module#ruby2_keywords for marking a method as passing keyword
447       arguments through a regular argument splat, useful when delegating
448       all arguments to another method in a way that can be backwards
449       compatible with older Ruby versions.  [Bug #16154]
451   [Modified methods]
453     * Module#autoload? now takes an +inherit+ optional argument, like
454       Module#const_defined?.  [Feature #15777]
456     * Module#name now always returns a frozen String. The returned String is
457       always the same for a given Module. This change is
458       experimental. [Feature #16150]
460 [NilClass / TrueClass / FalseClass]
462   [Modified methods]
464     * NilClass#to_s, TrueClass#to_s, and FalseClass#to_s now always return a
465       frozen String. The returned String is always the same for each of these
466       values. This change is experimental. [Feature #16150]
468 [ObjectSpace::WeakMap]
470   [Modified method]
472     * ObjectSpace::WeakMap#[]= now accepts special objects as either key or
473       values.  [Feature #16035]
475 [Proc]
477   [New method]
479     * Added Proc#ruby2_keywords for marking the proc as passing keyword
480       arguments through a regular argument splat, useful when delegating
481       all arguments to another method or proc in a way that can be backwards
482       compatible with older Ruby versions.  [Feature #16404]
484 [Range]
486   [New method]
488     * Added Range#minmax, with a faster implementation than Enumerable#minmax.
489       It returns a maximum that now corresponds to Range#max. [Bug #15807]
491   [Modified method]
493     * Range#=== now uses Range#cover? for String arguments, too (in Ruby 2.6, it was
494       changed from Range#include? for all types except strings). [Bug #15449]
497 [RubyVM]
499   [Removed method]
501     * +RubyVM.resolve_feature_path+ moved to
502       <code>$LOAD_PATH.resolve_feature_path</code>.  [Feature #15903] [Feature #15230]
504 [String]
506   [Unicode]
508     * Update Unicode version and Emoji version from 11.0.0 to
509       12.0.0.  [Feature #15321]
511     * Update Unicode version to 12.1.0, adding support for
512       U+32FF SQUARE ERA NAME REIWA.  [Feature #15195]
514     * Update Unicode Emoji version to 12.1. [Feature #16272]
516 [Symbol]
518   [New methods]
520     * Added Symbol#start_with? and Symbol#end_with? methods.  [Feature #16348]
522 [Time]
524   [New methods]
526     * Added Time#ceil method.  [Feature #15772]
528     * Added Time#floor method.  [Feature #15653]
530   [Modified method]
532     * Time#inspect is separated from Time#to_s and it shows
533       the time's sub second.  [Feature #15958]
535 [UnboundMethod]
537   [New method]
539     * Added UnboundMethod#bind_call method.  [Feature #15955]
541       <code>umethod.bind_call(obj, ...)</code> is semantically equivalent
542       to <code>umethod.bind(obj).call(...)</code>.  This idiom is used in
543       some libraries to call a method that is overridden.  The added
544       method does the same without allocation of an intermediate Method
545       object.
547           class Foo
548             def add_1(x)
549               x + 1
550             end
551           end
552           class Bar < Foo
553             def add_1(x) # override
554               x + 2
555             end
556           end
558           obj = Bar.new
559           p obj.add_1(1) #=> 3
560           p Foo.instance_method(:add_1).bind(obj).call(1) #=> 2
561           p Foo.instance_method(:add_1).bind_call(obj, 1) #=> 2
563 [Warning]
565   [New methods]
567     * Added Warning.[] and Warning.[]= to manage emitting/suppressing
568       some categories of warnings.  [Feature #16345] [Feature #16420]
570 [$LOAD_PATH]
572   [New method]
574     * Added <code>$LOAD_PATH.resolve_feature_path</code>.  [Feature #15903] [Feature #15230]
576 === Stdlib updates (outstanding ones only)
578 [Bundler]
580   * Upgrade to Bundler 2.1.2.
581     See https://github.com/bundler/bundler/releases/tag/v2.1.2
583 [CGI]
585   * CGI.escapeHTML becomes 2~5x faster when there is at least one escaped character.
586     See https://github.com/ruby/ruby/pull/2226
588 [CSV]
590   * Upgrade to 3.1.2.
591     See https://github.com/ruby/csv/blob/master/NEWS.md.
593 [Date]
595   * Date.jisx0301, Date#jisx0301, and Date.parse support the new Japanese
596     era.  [Feature #15742]
598 [Delegator]
600   * Object#DelegateClass accepts a block and module_evals it in the context
601     of the returned class, similar to Class.new and Struct.new.
603 [ERB]
605   * Prohibit marshaling ERB instance.
607 [IRB]
609   * Introduce syntax highlighting inspired by the Pry gem to Binding#irb
610     source lines, REPL input, and inspect output of some core-class objects.
612   * Introduce multiline editing mode provided by Reline.
614   * Show documentation when completion.
616   * Enable auto indent and save/load history by default.
618 [JSON]
620   * Upgrade to 2.3.0.
622 [Net::FTP]
624   * Add Net::FTP#features to check available features, and Net::FTP#option to
625     enable/disable each of them.  [Feature #15964]
627 [Net::HTTP]
629   * Add +ipaddr+ optional parameter to Net::HTTP#start to replace the address for
630     the TCP/IP connection. [Feature #5180]
632 [Net::IMAP]
634   * Add Server Name Indication (SNI) support.  [Feature #15594]
636 [open-uri]
638   * Warn open-uri's "open" method at Kernel.
639     Use URI.open instead.  [Misc #15893]
641   * The default charset of "text/*" media type is UTF-8 instead of
642     ISO-8859-1.  [Bug #15933]
644 [OptionParser]
646   * Now show "Did you mean?" for unknown options.  [Feature #16256]
648     test.rb:
650       require "optparse"
651       OptionParser.new do |opts|
652         opts.on("-f", "--foo", "foo") {|v| }
653         opts.on("-b", "--bar", "bar") {|v| }
654         opts.on("-c", "--baz", "baz") {|v| }
655       end.parse!
657     example:
659       $ ruby test.rb --baa
660       Traceback (most recent call last):
661       test.rb:7:in `<main>': invalid option: --baa (OptionParser::InvalidOption)
662       Did you mean?  baz
663                      bar
665 [Pathname]
667   * Pathname.glob now delegates 3 arguments to Dir.glob
668     to accept +base+ keyword. [Feature #14405]
670 [Racc]
672   * Merge 1.4.15 from upstream repository and added cli of racc.
674 [Reline]
676   * New stdlib that is compatible with the readline stdlib but is
677     implemented in pure Ruby. It also provides a multiline editing mode.
679 [REXML]
681   * Upgrade to 3.2.3.
682     See https://github.com/ruby/rexml/blob/master/NEWS.md.
684 [RSS]
686   * Upgrade to RSS 0.2.8.
687     See https://github.com/ruby/rss/blob/master/NEWS.md.
689 [RubyGems]
691   * Upgrade to RubyGems 3.1.2.
692     * https://github.com/rubygems/rubygems/releases/tag/v3.1.0
693     * https://github.com/rubygems/rubygems/releases/tag/v3.1.1
694     * https://github.com/rubygems/rubygems/releases/tag/v3.1.2
696 [StringScanner]
698   * Upgrade to 1.0.3.
699     See https://github.com/ruby/strscan/blob/master/NEWS.md.
701 === Compatibility issues (excluding feature bug fixes)
703 * The following libraries are no longer bundled gems.
704   Install corresponding gems to use these features.
705   * CMath (cmath gem)
706   * Scanf (scanf gem)
707   * Shell (shell gem)
708   * Synchronizer (sync gem)
709   * ThreadsWait (thwait gem)
710   * E2MM (e2mmap gem)
712 [Proc]
713   * The Proc#to_s format was changed. [Feature #16101]
715 [Range]
716   * Range#minmax used to iterate on the range to determine the maximum.
717     It now uses the same algorithm as Range#max. In rare cases (e.g.
718     ranges of Floats or Strings), this may yield different results. [Bug #15807]
720 === Stdlib compatibility issues (excluding feature bug fixes)
722 * Promote stdlib to default gems
723   * The following default gems were published on rubygems.org
724     * benchmark
725     * cgi
726     * delegate
727     * getoptlong
728     * net-pop
729     * net-smtp
730     * open3
731     * pstore
732     * readline
733     * readline-ext
734     * singleton
735   * The following default gems were only promoted at ruby-core,
736     but not yet published on rubygems.org.
737     * monitor
738     * observer
739     * timeout
740     * tracer
741     * uri
742     * yaml
743 * The <tt>did_you_mean</tt> gem has been promoted up to a default gem from a bundled gem
745 [pathname]
747   * Kernel#Pathname when called with a Pathname argument now returns
748     the argument instead of creating a new Pathname. This is more
749     similar to other Kernel methods, but can break code that modifies
750     the return value and expects the argument not to be modified.
752 [profile.rb, Profiler__]
754   * Removed from standard library. It was unmaintained since Ruby 2.0.0.
756 === C API updates
758 * Many <code>*_kw</code> functions have been added for setting whether
759   the final argument being passed should be treated as keywords. You
760   may need to switch to these functions to avoid keyword argument
761   separation warnings, and to ensure correct behavior in Ruby 3.
763 * The <code>:</code> character in rb_scan_args format string is now
764   treated as keyword arguments. Passing a positional hash instead of
765   keyword arguments will emit a deprecation warning.
767 * C API declarations with +ANYARGS+ are changed not to use +ANYARGS+.
768   See https://github.com/ruby/ruby/pull/2404
770 === Implementation improvements
772 [Fiber]
774   * Allow selecting different coroutine implementations by using
775     +--with-coroutine=+, e.g.
777          $ ./configure --with-coroutine=ucontext
778          $ ./configure --with-coroutine=copy
780   * Replace previous stack cache with fiber pool cache. The fiber pool
781     allocates many stacks in a single memory region. Stack allocation
782     becomes O(log N) and fiber creation is amortized O(1). Around 10x
783     performance improvement was measured in micro-benchmarks.
784     https://github.com/ruby/ruby/pull/2224
786 [File]
787   * File.realpath now uses realpath(3) on many platforms, which can
788     significantly improve performance. [Feature #15797]
790 [Hash]
791   * Change data structure of small Hash objects. [Feature #15602]
793 [Monitor]
794   * Monitor class is written in C-extension. [Feature #16255]
796 [Thread]
798   * VM stack memory allocation is now combined with native thread stack,
799     improving thread allocation performance and reducing allocation related
800     failures. Around 10x performance improvement was measured in micro-benchmarks.
802 [JIT]
804   * JIT-ed code is recompiled to less-optimized code when an optimization assumption is invalidated.
806   * Method inlining is performed when a method is considered as pure.
807     This optimization is still experimental and many methods are NOT considered as pure yet.
809   * The default value of +--jit-max-cache+ is changed from 1,000 to 100.
811   * The default value of +--jit-min-calls+ is changed from 5 to 10,000.
813 [RubyVM]
815   * Per-call-site method cache, which has been there since around 1.9, was
816     improved: cache hit rate raised from 89% to 94%.
817     See https://github.com/ruby/ruby/pull/2583
819 [RubyVM::InstructionSequence]
821   * RubyVM::InstructionSequence#to_binary method generates compiled binary.
822     The binary size is reduced. [Feature #16163]
824 === Miscellaneous changes
826 * Support for IA64 architecture has been removed. Hardware for testing was
827   difficult to find, native fiber code is difficult to implement, and it added
828   non-trivial complexity to the interpreter. [Feature #15894]
830 * Require compilers to support C99. [Misc #15347]
832   * Details of our dialect: https://bugs.ruby-lang.org/projects/ruby-master/wiki/C99
834 * Ruby's upstream repository is changed from Subversion to Git.
836   * https://git.ruby-lang.org/ruby.git
838   * RUBY_REVISION class is changed from Integer to String.
840   * RUBY_DESCRIPTION includes Git revision instead of Subversion's one.
842 * Support built-in methods in Ruby with the <code>_\_builtin_</code> syntax. [Feature #16254]
844   Some methods are defined in *.rb (such as trace_point.rb).
845   For example, it is easy to define a method which accepts keyword arguments.