summaryrefslogtreecommitdiff
path: root/NEWS
blob: e1adb5115dbcbce6fb9a6a6a6dd993d4824965e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
# -*- rdoc -*-

= 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. <tt>https://bugs.ruby-lang.org/issues/$FEATURE_OR_BUG_NUMBER</tt>).

== Changes since the 2.6.0 release

=== Language changes

==== Pattern matching

* Pattern matching is introduced as an experimental feature. [Feature #14912]

    case [0, [1, 2, 3]]
    in [a, [b, *c]]
      p a #=> 0
      p b #=> 1
      p c #=> [2, 3]
    end

    case {a: 0, b: 1}
    in {a: 0, x: 1}
      :unreachable
    in {a: 0, b: var}
      p var #=> 1
    end

    case -1
    in 0 then :unreachable
    in 1 then :unreachable
    end #=> NoMatchingPatternError

    json = <<END
    {
      "name": "Alice",
      "age": 30,
      "children": [{ "name": "Bob", "age": 2 }]
    }
    END

    JSON.parse(json, symbolize_names: true) in {name: "Alice", children: [{name: name, age: age}]}

    p name #=> "Bob"
    p age  #=> 2

    JSON.parse(json, symbolize_names: true) in {name: "Alice", children: [{name: "Charlie", age: age}]}
    #=> NoMatchingPatternError

* See the following slides for more details:
  * https://speakerdeck.com/k_tsj/pattern-matching-new-feature-in-ruby-2-dot-7
  * Note that the slides are slightly obsolete.

* The warning against pattern matching can be suppressed with
  {-W:no-experimental option}[#label-Warning+option].

==== The spec of keyword arguments is changed towards 3.0

* Automatic conversion of keyword arguments and positional arguments is
  deprecated, and conversion will be removed in Ruby 3.  [Feature #14183]

  * When a method call passes a Hash at the last argument, and when it
    passes no keywords, and when the called method accepts keywords,
    a warning is emitted.  To continue treating the hash as keywords,
    add a double splat operator to avoid the warning and ensure
    correct behavior in Ruby 3.

      def foo(key: 42); end; foo({key: 42})   # warned
      def foo(**kw);    end; foo({key: 42})   # warned
      def foo(key: 42); end; foo(**{key: 42}) # OK
      def foo(**kw);    end; foo(**{key: 42}) # OK

  * When a method call passes keywords to a method that accepts keywords,
    but it does not pass enough required positional arguments, the
    keywords are treated as a final required positional argument, and a
    warning is emitted.  Pass the argument as a hash instead of keywords
    to avoid the warning and ensure correct behavior in Ruby 3.

      def foo(h, **kw); end; foo(key: 42)      # warned
      def foo(h, key: 42); end; foo(key: 42)   # warned
      def foo(h, **kw); end; foo({key: 42})    # OK
      def foo(h, key: 42); end; foo({key: 42}) # OK

  * When a method accepts specific keywords but not a keyword splat, and
    a hash or keywords splat is passed to the method that includes both
    Symbol and non-Symbol keys, the hash will continue to be split, and
    a warning will be emitted.  You will need to update the calling code
    to pass separate hashes to ensure correct behavior in Ruby 3.

      def foo(h={}, key: 42); end; foo("key" => 43, key: 42)   # warned
      def foo(h={}, key: 42); end; foo({"key" => 43, key: 42}) # warned
      def foo(h={}, key: 42); end; foo({"key" => 43}, key: 42) # OK

  * If a method does not accept keywords, and is called with keywords,
    the keywords are still treated as a positional hash, with no warning.
    This behavior will continue to work in Ruby 3.

      def foo(opt={});  end; foo( key: 42 )   # OK

* Non-symbols are allowed as keyword argument keys if the method accepts
  arbitrary keywords. [Feature #14183]

  * Non-Symbol keys in a keyword arguments hash were prohibited in 2.6.0,
    but are now allowed again.  [Bug #15658]

      def foo(**kw); p kw; end; foo("str" => 1) #=> {"str"=>1}

* <code>**nil</code> is allowed in method definitions to explicitly mark
  that the method accepts no keywords. Calling such a method with keywords
  will result in an ArgumentError. [Feature #14183]

    def foo(h, **nil); end; foo(key: 1)       # ArgumentError
    def foo(h, **nil); end; foo(**{key: 1})   # ArgumentError
    def foo(h, **nil); end; foo("str" => 1)   # ArgumentError
    def foo(h, **nil); end; foo({key: 1})     # OK
    def foo(h, **nil); end; foo({"str" => 1}) # OK

* Passing an empty keyword splat to a method that does not accept keywords
  no longer passes an empty hash, unless the empty hash is necessary for
  a required parameter, in which case a warning will be emitted.  Remove
  the double splat to continue passing a positional hash.  [Feature #14183]

    h = {}; def foo(*a) a end; foo(**h) # []
    h = {}; def foo(a) a end; foo(**h)  # {} and warning
    h = {}; def foo(*a) a end; foo(h)   # [{}]
    h = {}; def foo(a) a end; foo(h)    # {}

* Above warnings can be suppressed also with {-W:no-deprecated option}[#label-Warning+option].

==== Numbered parameters

* Numbered parameters as default block parameters are introduced.
  [Feature #4475]

    [1, 2, 10].map { _1.to_s(16) }    #=> ["1", "2", "a"]
    [[1, 2], [3, 4]].map { _1 + _2 }  #=> [3, 7]

  You can still define a local variable named +_1+ and so on,
  and that is honored when present, but renders a warning.

    _1 = 0            #=> warning: `_1' is reserved for numbered parameter; consider another name
    [1].each { p _1 } # prints 0 instead of 1

==== proc/lambda without block is deprecated

* Proc.new and Kernel#proc with no block in a method called with a block is
  warned now.

    def foo
      proc
    end
    foo { puts "Hello" } #=> warning: Capturing the given block using Kernel#proc is deprecated; use `&block` instead

  This warning can be suppressed with {-W:no-deprecated option}[#label-Warning+option].

* Kernel#lambda with no block in a method called with a block raises an exception.

    def bar
      lambda
    end
    bar { puts "Hello" } #=> tried to create Proc object without a block (ArgumentError)

==== Other miscellaneous changes

* A beginless range is experimentally introduced.  It might be useful
  in +case+, new call-sequence of the <code>Comparable#clamp</code>,
  constants and DSLs.  [Feature #14799]

     ary[..3]  # identical to ary[0..3]

     case RUBY_VERSION
     when ..."2.4" then puts "EOL"
     # ...
     end

     age.clamp(..100)

     where(sales: ..100)

* Setting <code>$;</code> to a non-nil value is warned now. [Feature #14240]
  Use of it in String#split is warned too.
  This warning can be suppressed with {-W:no-deprecated option}[#label-Warning+option].

* Setting <code>$,</code> to a non-nil value is warned now. [Feature #14240]
  Use of it in Array#join is warned too.
  This warning can be suppressed with {-W:no-deprecated option}[#label-Warning+option].

* Quoted here-document identifiers must end within the same line.

     <<"EOS
     " # This had been warned since 2.4; Now it raises a SyntaxError
     EOS

* The flip-flop syntax deprecation is reverted. [Feature #5400]

* Comment lines can be placed between fluent dot now.

    foo
      # .bar
      .baz # => foo.baz

* Calling a private method with a literal +self+ as the receiver
  is now allowed. [Feature #11297] [Feature #16123]

* Modifier rescue now operates the same for multiple assignment as single
  assignment. [Bug #8279]

    a, b = raise rescue [1, 2]
    # Previously parsed as: (a, b = raise) rescue [1, 2]
    # Now parsed as:         a, b = (raise rescue [1, 2])

* +yield+ in singleton class syntax is warned and will be deprecated later. [Feature #15575].

   def foo
     class << Object.new
       yield #=> warning: `yield' in class syntax will not be supported from Ruby 3.0. [Feature #15575]
     end
   end
   foo { p :ok }

  This warning can be suppressed with {-W:no-deprecated option}[#label-Warning+option].

* Argument forwarding by <code>(...)</code> is introduced. [Feature #16253]

    def foo(...)
      bar(...)
    end

  All arguments to +foo+ are forwarded to +bar+, including keyword and
  block arguments.
  Note that the parentheses are mandatory.  <code>bar ...</code> is parsed
  as an endless range.

* Access and setting of <code>$SAFE</code> is now always warned. <code>$SAFE</code>
  will become a normal global variable in Ruby 3.0. [Feature #16131]

* <code>Object#{taint,untaint,trust,untrust}</code> and related functions in the C-API
  no longer have an effect (all objects are always considered untainted), and are now
  warned in verbose mode. This warning will be disabled even in non-verbose mode in
  Ruby 3.0, and the methods and C functions will be removed in Ruby 3.2. [Feature #16131]

* Refinements take place at Object#method and Module#instance_method. [Feature #15373]

=== Command line options

==== Warning option

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

* To suppress deprecation warnings:

    $ ruby -e '$; = ""'
    -e:1: warning: `$;' is deprecated

    $ ruby -W:no-deprecated -e '$; = //'

* It works with the +RUBYOPT+ environment variable:

    $ RUBYOPT=-W:no-deprecated ruby -e '$; = //'

* To suppress experimental feature warnings:

    $ ruby -e '0 in a'
    -e:1: warning: Pattern matching is experimental, and the behavior may change in future versions of Ruby!

    $ ruby -W:no-experimental -e '0 in a'

* To suppress both by using +RUBYOPT+, set space separated values:

    $ RUBYOPT='-W:no-deprecated -W:no-experimental' ruby -e '($; = "") in a'

See also Warning in {Core classes updates}[#label-Core+classes+updates+-28outstanding+ones+only-29].

=== Core classes updates (outstanding ones only)

Array::

  New methods::

    * Added Array#intersection. [Feature #16155]

    * Added Array#minmax, with a faster implementation than Enumerable#minmax. [Bug #15929]

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 <code>0 <=> 0i</code> 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]

Fiber::

  New method::

    * Added Fiber#raise that behaves like Fiber#resume but raises an
      exception on the resumed fiber.  [Feature #10344]

File::

  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::

    * Added FrozenError#receiver to return the frozen object on which
      modification was attempted.  To set this object when raising
      FrozenError in Ruby code, FrozenError.new accepts a +:receiver+
      option.  [Feature #15751]

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:
      https://bugs.ruby-lang.org/issues/15626

IO::

  New method::

    * Added IO#set_encoding_by_bom to check the BOM and set the external
      encoding.  [Bug #15210]

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::

    * Method#inspect shows more information. [Feature #14145]

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::

    * Module#autoload? now takes an +inherit+ optional argument, like
      Module#const_defined?.  [Feature #15777]

    * Module#name now always returns a frozen String. The returned String is
      always the same for a given Module. This change is
      experimental. [Feature #16150]

NilClass / TrueClass / FalseClass::

  Modified methods::

    * NilClass#to_s, TrueClass#to_s, and FalseClass#to_s now always return a
      frozen String. The returned String is always the same for each of these
      values. This change is experimental. [Feature #16150]

ObjectSpace::WeakMap::

  Modified method::

    * ObjectSpace::WeakMap#[]= now accepts special objects as either key or
      values.  [Feature #16035]

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::

    * Added Range#minmax, with a faster implementation than Enumerable#minmax.
      It returns a maximum that now corresponds to Range#max. [Bug #15807]

  Modified method::

    * Range#=== now uses Range#cover? for String arguments, too (in Ruby 2.6, it was
      changed from Range#include? for all types except strings). [Bug #15449]


RubyVM::

  Removed method::

    * +RubyVM.resolve_feature_path+ moved to
      <code>$LOAD_PATH.resolve_feature_path</code>.  [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::

    * Added Symbol#start_with? and Symbol#end_with? methods.  [Feature #16348]

Time::

  New methods::

    * Added Time#ceil method.  [Feature #15772]

    * Added Time#floor method.  [Feature #15653]

  Modified method::

    * Time#inspect is separated from Time#to_s and it shows
      the time's sub second.  [Feature #15958]

UnboundMethod::

  New method::

    * Added UnboundMethod#bind_call method.  [Feature #15955]

      <code>umethod.bind_call(obj, ...)</code> is semantically equivalent
      to <code>umethod.bind(obj).call(...)</code>.  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 <code>$LOAD_PATH.resolve_feature_path</code>.  [Feature #15903] [Feature #15230]

=== Stdlib updates (outstanding ones only)

Bundler::

  * Upgrade to Bundler 2.1.2.
    See https://github.com/bundler/bundler/releases/tag/v2.1.2

CGI::

  * CGI.escapeHTML becomes 2~5x faster when there is at least one escaped character.
    See https://github.com/ruby/ruby/pull/2226

CSV::

  * Upgrade to 3.1.2.
    See https://github.com/ruby/csv/blob/master/NEWS.md.

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::

  * Upgrade to 3.2.3.
    See https://github.com/ruby/rexml/blob/master/NEWS.md.

RSS::

  * Upgrade to RSS 0.2.8.
    See https://github.com/ruby/rss/blob/master/NEWS.md.

RubyGems::

  * Upgrade to RubyGems 3.1.2.
    * https://github.com/rubygems/rubygems/releases/tag/v3.1.0
    * https://github.com/rubygems/rubygems/releases/tag/v3.1.1
    * https://github.com/rubygems/rubygems/releases/tag/v3.1.2

StringScanner::

  * Upgrade to 1.0.3.
    See https://github.com/ruby/strscan/blob/master/NEWS.md.

=== Compatibility issues (excluding feature bug fixes)

* The following libraries are no longer bundled gems.
  Install corresponding gems to use these features.
  * CMath (cmath gem)
  * Scanf (scanf gem)
  * Shell (shell gem)
  * Synchronizer (sync gem)
  * ThreadsWait (thwait gem)
  * E2MM (e2mmap gem)

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)

* Promote stdlib to default gems
  * The following default gems were published on rubygems.org
    * benchmark
    * cgi
    * delegate
    * getoptlong
    * net-pop
    * net-smtp
    * open3
    * pstore
    * readline
    * readline-ext
    * singleton
  * The following default gems were only promoted at ruby-core,
    but not yet published on rubygems.org.
    * monitor
    * observer
    * timeout
    * tracer
    * uri
    * yaml
* The <tt>did_you_mean</tt> gem has been promoted up to a default gem from a bundled gem

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

* Many <code>*_kw</code> functions have been added for setting whether
  the final argument being passed should be treated as keywords. You
  may need to switch to these functions to avoid keyword argument
  separation warnings, and to ensure correct behavior in Ruby 3.

* The <code>:</code> character in rb_scan_args format string is now
  treated as keyword arguments. Passing a positional hash instead of
  keyword arguments will emit a deprecation warning.

* C API declarations with +ANYARGS+ are changed not to use +ANYARGS+.
  See https://github.com/ruby/ruby/pull/2404

=== 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.
    https://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 https://github.com/ruby/ruby/pull/2583

RubyVM::InstructionSequence::

  * RubyVM::InstructionSequence#to_binary method generates compiled binary.
    The binary size is reduced. [Feature #16163]

=== Miscellaneous changes

* Support for IA64 architecture has been removed. Hardware for testing was
  difficult to find, native fiber code is difficult to implement, and it added
  non-trivial complexity to the interpreter. [Feature #15894]

* Require compilers to support C99. [Misc #15347]

  * Details of our dialect: https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/C99

* Ruby's upstream repository is changed from Subversion to Git.

  * https://git.ruby-lang.org/ruby.git

  * RUBY_REVISION class is changed from Integer to String.

  * RUBY_DESCRIPTION includes Git revision instead of Subversion's one.

* Support built-in methods in Ruby with the <code>_\_builtin_</code> syntax. [Feature #16254]

  Some methods are defined in *.rb (such as trace_point.rb).
  For example, it is easy to define a method which accepts keyword arguments.