Skip to content

Commit a214752

Browse files
committed
Advent of Changelog: Day 20
1 parent 7f65d0f commit a214752

File tree

5 files changed

+145
-65
lines changed

5 files changed

+145
-65
lines changed

3.2.md

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ description: Ruby 3.2 full and annotated changelog
88
# Ruby 3.2
99

1010
* **Released at:** Dec 25, 2022 (<a class="github" href="https://github.com/ruby/ruby/blob/ruby_3_2/NEWS.md">NEWS.md</a> file)
11-
* **Status (as of Dec 18, 2023):** 3.2.2 is current _stable_
11+
* **Status (as of Dec 20, 2023):** 3.2.2 is current _stable_
1212
* **This document first published:** Feb 4, 2022
13-
* **Last change to this document:** Dec 18, 2023
13+
* **Last change to this document:** Dec 20, 2023
1414

1515
<!--
1616
* **Reason:**
@@ -504,20 +504,7 @@ Returns list of refinements the module defines.
504504
* **Discussion:** <a class="tracker feature" href="https://bugs.ruby-lang.org/issues/12737">Feature #12737</a>
505505
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.2/Refinement.html#method-i-refined_class"><code>Refinement#refined_class</code></a>
506506
* **Code:** See example above that demonstrates usage of `#refined_class` together with `Module#refinements`.
507-
* **Note:** The name of the method implies only classes can be refined, which is not true; modules can be refined also, and `refined_class` will promptly return them:
508-
```ruby
509-
module BetterEnum
510-
refine Enumerable do
511-
def each2(&block) = each_slice(2, &block)
512-
end
513-
end
514-
515-
BetterEnum.refinements[0].refined_class #=> Enumerable
516-
517-
using BetterEnum
518-
(1..6).each2.to_a #=> [[1, 2], [3, 4], [5, 6]]
519-
```
520-
Currently [discussed](https://bugs.ruby-lang.org/issues/19366).
507+
* **Follow-ups:** [3.3](3.3.html#refinementrefined_class-is-renamed-to-refinementtarget): Renamed to `#target`, because not only classes can be refined, modules too.
521508

522509
#### `Module.used_refinements`[](#moduleused_refinements)
523510

@@ -622,7 +609,9 @@ Several method were added that operate on multibyte strings at byte-offset level
622609
str.byteslice(1..3) #=> "\xB2і" -- works, even if the slice is mid-character
623610
str.bytesplice(1..3, '...') # offset 1 does not land on character boundary (IndexError)
624611
```
625-
* **Note:** After 3.2 release, `bytesplice` behavior [had changed](https://bugs.ruby-lang.org/issues/19314#note-8) to return `self` instead of replacement string.
612+
* **Note:**
613+
* After 3.2 release, `bytesplice` behavior [had changed](https://bugs.ruby-lang.org/issues/19314#note-8) to return `self` instead of replacement string.
614+
* [3.3](3.3.html#stringbytesplice-new-arguments-to-select-a-portion-of-the-replacement-string): parameters added to `bytesplice` to allow partial copy of the buffer.
626615
627616
#### `String#dedup` as an alias for `-"string"`[](#stringdedup-as-an-alias-for--string)
628617

@@ -753,6 +742,7 @@ The new protocol for `Time.new` is introduced, that parses Time from string.
753742
#=> 2023-01-29 00:00:00 +0200
754743
```
755744
* `Time.new('2023')` works, too, but it is a feature that worked before (force-conversion of singular year argument to integer), see <a class="tracker bug" href="https://bugs.ruby-lang.org/issues/19293">Bug #19293</a>. It will probably be deprecated, but can't be quickly removed due to backward compatibility.
745+
* **Follow-ups:**: [3.3](3.3.html#timenew-with-string-argument-became-stricter): `Time.new` became stricting, accepting only fully-specified date-time.
756746

757747
### `Struct` and `Data`[](#struct-and-data)
758748

@@ -891,7 +881,8 @@ A new class for containing value objects: it is somewhat similar to `Struct` (an
891881
res
892882
#=> #<data Result array=[4, 3, 2, 1]>
893883
```
894-
* `#with` method in Ruby 3.2 is naive and just copies all old and new attributes to the new instance, without invoking any custom initialization methods. In the next version, though, it [expected to call `#initialize`](https://bugs.ruby-lang.org/issues/19259):
884+
* **Follow-ups:**
885+
* `#with` method in Ruby 3.2.0 was naive and just copies all old and new attributes to the new instance, without invoking any custom initialization methods. It was fixed to [call `#initialize`](https://bugs.ruby-lang.org/issues/19259) in 3.2.2:
895886
```ruby
896887
Point = Data.define(:x, :y) do
897888
def initialize(x:, y:) = super(x: x.to_i, y: y.to_i)
@@ -1128,7 +1119,7 @@ Previously a part of standard library, Set (a collection of unique elements) was
11281119
t.dup.tag #=> nil
11291120
```
11301121
This is a [bug](https://bugs.ruby-lang.org/issues/19362).
1131-
* **Follow-ups:** [Since Ruby 3.3](3.3.html#procdup-and-clone-call-initialize_dup-and-initialize_copy), `#dup` properly invokes `#initialize_dup`
1122+
* **Follow-ups:** [3.3](3.3.html#procdup-and-clone-call-initialize_dup-and-initialize_copy): `#dup` properly invokes `#initialize_dup`.
11321123

11331124
#### `Proc#parameters`: new keyword argument `lambda: true/false`[](#procparameters-new-keyword-argument-lambda-truefalse)
11341125

@@ -1163,7 +1154,7 @@ Previously a part of standard library, Set (a collection of unique elements) was
11631154
11641155
#### `Method#public?`, `#protected?`, and `#private?` are removed[](#methodpublic-protected-and-private-are-removed)
11651156
1166-
Predicates to check method visibility added in Ruby 3.1 were reverted.
1157+
Predicates to check method visibility [added in Ruby 3.1](3.1.html#methodunboundmethod-public-private-protected) were reverted.
11671158
11681159
* **Reason:** The new feature implementation have led to several bugs with `Method` class behavior; while investigating the root cause for those bugs, Matz have decided that method's visibility is not its inherent property, but rather a property of the module/object that owns the method, and as such, is already present in form of `Module#{private,public,protected}_instance_methods` and `Object#{private,public,protected}_methods`
11691160
* **Discussion:** <a class="tracker feature" href="https://bugs.ruby-lang.org/issues/11689#note-24#note-24">Feature #11689<small>#note-24</small></a>

3.3.md

Lines changed: 69 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ description: Ruby 3.3 full and annotated changelog
88
# Ruby 3.3
99

1010
* **Released at:** Dec 25, 2023 ([NEWS.md](TODO) file)
11-
* **Status (as of Dec 19, 2023):** TODO
11+
* **Status (as of Dec 20, 2023):** TODO
1212
* **This document first published:** Dec 25, 2023
13-
* **Last change to this document:** Dec 19, 2023
13+
* **Last change to this document:** Dec 20, 2023
1414

1515
<!--
1616
* **Reason:**
@@ -24,11 +24,11 @@ description: Ruby 3.3 full and annotated changelog
2424

2525
> 3.3 has many important _internal_ changes related to performance optimizations, parser, and JIT (which are mostly of scope of what I am able and willing to cover), but somewhat lighter on the "small quality of life improvement" side.
2626
27-
* [`it` will become anonymous block argument in 3.4]()
28-
* [`Module#set_temporary_name`]()
29-
* [`ObjectSpace::WeakKeyMap`]()
30-
* [`Range#overlap?`]()
31-
* [`Fiber#kill`]()
27+
* [`it` will become anonymous block argument in 3.4](#standalone-it-in-blocks-will-become-anonymous-argument-in-ruby-34)
28+
* [`Module#set_temporary_name`](#moduleset_temporary_name)
29+
* [`ObjectSpace::WeakKeyMap`](#objectspaceweakkeymap)
30+
* [`Range#overlap?`](#overlap)
31+
* [`Fiber#kill`](#fiberkill)
3232

3333
## Language changes[](#language-changes)
3434

@@ -295,6 +295,32 @@ The low-level string manipulation method now allows to provide a coordinates of
295295
```
296296
* **Notes:** While `symbolize_names:` might looks somewhat strange (usually we talk about hash _keys_), it is done for consistency with Ruby standard library's <a class="ruby-doc" href="https://docs.ruby-lang.org/en/master/JSON.html#module-JSON-label-Output+Options"><code>`JSON.parse`</code></a> signature, which inherited the terminology from the JSON specification.
297297

298+
### `Time.new` with string argument became stricter[](#timenew-with-string-argument-became-stricter)
299+
300+
The method now requires fully-specified date-time string.
301+
302+
* **Discussion:** [Bug #19293]
303+
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/master/Time.html#method-c-new"><code>Time#new</code></a>
304+
* **Code:**
305+
```ruby
306+
Time.new('2023-12-20')
307+
# Ruby 3.2: #=> 2023-12-20 00:00:00 +0200
308+
# Ruby 3.3: in `initialize': no time information (ArgumentError)
309+
310+
Time.new('2023-12')
311+
# Ruby 3.2: #=> 2023-12-01 00:00:00 +0200
312+
# Ruby 3.3: in `initialize': no time information (ArgumentError)
313+
314+
# Singular year is still works:
315+
Time.new('2023')
316+
#=> 2023-01-01 00:00:00 +0200
317+
318+
# ...because it is documented behavior of Time.new to accept
319+
# strings that are numeric and treat them as numbers:
320+
Time.new('2023', '12', '20')
321+
#=> 2023-12-20 00:00:00 +0200
322+
```
323+
298324
### `Array#pack` and `String#unpack`: raise `ArgumentError` for unknown directives[](#arraypack-and-stringunpack-raise-argumenterror-for-unknown-directives)
299325

300326
* **Discussion:** [Bug #19150]
@@ -519,7 +545,7 @@ Two methods to accept an integer file descriptor as an argument: `for_fd` create
519545
```
520546
* **Notes:**
521547
* The functionality is only supported on POSIX platforms;
522-
* The initial [ticket](https://bugs.ruby-lang.org/issues/19347) only proposed to find a way to be able to change a current directory to one specified by a descriptor (i.e., what eventually became `.fchdir`), but during the discussion a need were discovered for a generic instantiation of a `Dir` instance from the descriptor (what became `from_fd`), as well as a generic way to change the current directory to one specified by `Dir` instance ([`#chdir`](TODO), which is not related to descriptors but is generically useful).
548+
* The initial [ticket](https://bugs.ruby-lang.org/issues/19347) only proposed to find a way to be able to change a current directory to one specified by a descriptor (i.e., what eventually became `.fchdir`), but during the discussion a need were discovered for a generic instantiation of a `Dir` instance from the descriptor (what became `from_fd`), as well as a generic way to change the current directory to one specified by `Dir` instance ([`#chdir`](#dirchdir), which is not related to descriptors but is generically useful).
523549

524550
#### `Dir#chdir`[](#dirchdir)
525551

@@ -574,6 +600,27 @@ An instance method version of <a class="ruby-doc" href="https://docs.ruby-lang.o
574600
```
575601
* As the impact of the change might be big, note that target version for removal is set to **4.0**. To the best of my knowledge, there are no set date for major version yet.
576602

603+
### `NoMethodError`: change of rendering logic[](#nomethoderror-change-of-rendering-logic)
604+
605+
`NoMethodError` doesn't use target object's `#inspect` in its message, and renders "instance of ClassName" instead.
606+
607+
* **Reason:** While the `#inspect` of the object which failed to respond might be convenient in the error's output, it also might be extremely inefficient and confusing when the object is large and doesn't have `#inspect` redefined to something sensible. It is impossible to require all user objects to redefine `#inspect`, and even if it is redefined, it might be short yet inefficient; so the lesser of evils was chosen and exception's message became more efficient even if less informative.
608+
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/master/NoMethodError.html"><code>NoMethodError</code></a>
609+
* **Code:**
610+
```ruby
611+
"hello".to_ary
612+
# Ruby 3.2: undefined method `to_ary' for "hello":String (NoMethodError)
613+
# Ruby 3.3: undefined method `to_ary' for an instance of String (NoMethodError)
614+
615+
# But also, for some complicated data structure:
616+
([{name: 'User 1', role: 'admin'}] * 100).to_josn # typo
617+
# Ruby 3.2: undefined method `to_josn' for [{:name=>"User 1", :role=>"admin"}, {:name=>"User 1", :role=>"admin"}, ...
618+
# ....10 lines of console output....
619+
# ..., {:name=>"User 1", :role=>"admin"}]:Array (NoMethodError)
620+
#
621+
# Ruby 3.3: undefined method `to_josn' for an instance of Array (NoMethodError)
622+
```
623+
577624
### `Fiber#kill`[](#fiberkill)
578625

579626
Terminates the Fiber by sending an exception inside it.
@@ -869,22 +916,22 @@ A few changes to mention, though:
869916

870917
_This means that if your dependencies are managed by Bundler and your code depend on `racc`, it should be added to a `Gemfile`._
871918

872-
* racc 1.7.3
919+
* <a class="github" href="https://github.com/ruby/racc">racc</a> 1.7.3
873920

874921
#### Gems that are warned to become bundled in the next version[](#gems-that-are-warned-to-become-bundled-in-the-next-version)
875922

876923
These gems wouldn't in a Bundler-managed environment unless explicitly added to `Gemfile` since the next version of Ruby. For now, requiring them in such environment would produce a warning. Discussion: [Feature #19351] (initial proposal to promote many gems, which then was deemed problematic), [Feature #19776] (the warning proposal)
877924

878-
* abbrev
879-
* base64
880-
* bigdecimal
881-
* csv
882-
* drb
883-
* getoptlong
884-
* mutex_m
885-
* nkf
886-
* observer
887-
* racc
888-
* resolv-replace
889-
* rinda
890-
* syslog
925+
* <a class="github" href="https://github.com/ruby/abbrev">abbrev</a>
926+
* <a class="github" href="https://github.com/ruby/base64">base64</a>
927+
* <a class="github" href="https://github.com/ruby/bigdecimal">bigdecimal</a>
928+
* <a class="github" href="https://github.com/ruby/csv">csv</a>
929+
* <a class="github" href="https://github.com/ruby/drb">drb</a>
930+
* <a class="github" href="https://github.com/ruby/getoptlong">getoptlong</a>
931+
* <a class="github" href="https://github.com/ruby/mutex_m">mutex_m</a>
932+
* <a class="github" href="https://github.com/ruby/nkf">nkf</a>
933+
* <a class="github" href="https://github.com/ruby/observer">observer</a>
934+
* <a class="github" href="https://github.com/ruby/racc">racc</a>
935+
* <a class="github" href="https://github.com/ruby/resolv-replace">resolv-replace</a>
936+
* <a class="github" href="https://github.com/ruby/rinda">rinda</a>
937+
* <a class="github" href="https://github.com/ruby/syslog">syslog</a>

_data/book.yml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,11 @@ chapters:
106106
</blockquote>
107107
108108
<ul>
109-
<li><a href=""><code>it</code> will become anonymous block argument in 3.4</a></li>
110-
<li><a href=""><code>Module#set_temporary_name</code></a></li>
111-
<li><a href=""><code>ObjectSpace::WeakKeyMap</code></a></li>
112-
<li><a href=""><code>Range#overlap?</code></a></li>
113-
<li><a href=""><code>Fiber#kill</code></a></li>
109+
<li><code>it</code> will become anonymous block argument in 3.4</li>
110+
<li><code>Module#set_temporary_name</code></li>
111+
<li><code>ObjectSpace::WeakKeyMap</code></li>
112+
<li><code>Range#overlap?</code></li>
113+
<li><code>Fiber#kill</code></li>
114114
</ul>
115115
116116
<p><a href="https://rubyreferences.github.io/rubychanges/3.3.html">Read more »</a></p>
@@ -144,6 +144,8 @@ chapters:
144144
- title: "<code>MatchData#named_captures</code>: <code>symbolize_names:</code>
145145
argument"
146146
path: "/3.3.html#matchdatanamed_captures-symbolize_names-argument"
147+
- title: "<code>Time.new</code> with string argument became stricter"
148+
path: "/3.3.html#timenew-with-string-argument-became-stricter"
147149
- title: "<code>Array#pack</code> and <code>String#unpack</code>: raise <code>ArgumentError</code>
148150
for unknown directives"
149151
path: "/3.3.html#arraypack-and-stringunpack-raise-argumenterror-for-unknown-directives"
@@ -173,6 +175,8 @@ chapters:
173175
path: "/3.3.html#dirchdir"
174176
- title: Deprecate subprocess creation with method dedicated to files
175177
path: "/3.3.html#deprecate-subprocess-creation-with-method-dedicated-to-files"
178+
- title: "<code>NoMethodError</code>: change of rendering logic"
179+
path: "/3.3.html#nomethoderror-change-of-rendering-logic"
176180
- title: "<code>Fiber#kill</code>"
177181
path: "/3.3.html#fiberkill"
178182
- title: Internals

_src/3.2.md

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -504,20 +504,7 @@ Returns list of refinements the module defines.
504504
* **Discussion:** [Feature #12737](https://bugs.ruby-lang.org/issues/12737)
505505
* **Documentation:** [Refinement#refined_class](https://docs.ruby-lang.org/en/3.2/Refinement.html#method-i-refined_class)
506506
* **Code:** See example above that demonstrates usage of `#refined_class` together with `Module#refinements`.
507-
* **Note:** The name of the method implies only classes can be refined, which is not true; modules can be refined also, and `refined_class` will promptly return them:
508-
```ruby
509-
module BetterEnum
510-
refine Enumerable do
511-
def each2(&block) = each_slice(2, &block)
512-
end
513-
end
514-
515-
BetterEnum.refinements[0].refined_class #=> Enumerable
516-
517-
using BetterEnum
518-
(1..6).each2.to_a #=> [[1, 2], [3, 4], [5, 6]]
519-
```
520-
Currently [discussed](https://bugs.ruby-lang.org/issues/19366).
507+
* **Follow-ups:** [3.3](3.3.html#refinementrefined_class-is-renamed-to-refinementtarget): Renamed to `#target`, because not only classes can be refined, modules too.
521508

522509
#### `Module.used_refinements`
523510

@@ -622,7 +609,9 @@ Several method were added that operate on multibyte strings at byte-offset level
622609
str.byteslice(1..3) #=> "\xB2і" -- works, even if the slice is mid-character
623610
str.bytesplice(1..3, '...') # offset 1 does not land on character boundary (IndexError)
624611
```
625-
* **Note:** After 3.2 release, `bytesplice` behavior [had changed](https://bugs.ruby-lang.org/issues/19314#note-8) to return `self` instead of replacement string.
612+
* **Note:**
613+
* After 3.2 release, `bytesplice` behavior [had changed](https://bugs.ruby-lang.org/issues/19314#note-8) to return `self` instead of replacement string.
614+
* [3.3](3.3.html#stringbytesplice-new-arguments-to-select-a-portion-of-the-replacement-string): parameters added to `bytesplice` to allow partial copy of the buffer.
626615
627616
#### `String#dedup` as an alias for `-"string"`
628617

@@ -753,6 +742,7 @@ The new protocol for `Time.new` is introduced, that parses Time from string.
753742
#=> 2023-01-29 00:00:00 +0200
754743
```
755744
* `Time.new('2023')` works, too, but it is a feature that worked before (force-conversion of singular year argument to integer), see [Bug #19293](https://bugs.ruby-lang.org/issues/19293). It will probably be deprecated, but can't be quickly removed due to backward compatibility.
745+
* **Follow-ups:**: [3.3](3.3.html#timenew-with-string-argument-became-stricter): `Time.new` became stricting, accepting only fully-specified date-time.
756746

757747
### `Struct` and `Data`
758748

@@ -891,7 +881,8 @@ A new class for containing value objects: it is somewhat similar to `Struct` (an
891881
res
892882
#=> #<data Result array=[4, 3, 2, 1]>
893883
```
894-
* `#with` method in Ruby 3.2 is naive and just copies all old and new attributes to the new instance, without invoking any custom initialization methods. In the next version, though, it [expected to call `#initialize`](https://bugs.ruby-lang.org/issues/19259):
884+
* **Follow-ups:**
885+
* `#with` method in Ruby 3.2.0 was naive and just copies all old and new attributes to the new instance, without invoking any custom initialization methods. It was fixed to [call `#initialize`](https://bugs.ruby-lang.org/issues/19259) in 3.2.2:
895886
```ruby
896887
Point = Data.define(:x, :y) do
897888
def initialize(x:, y:) = super(x: x.to_i, y: y.to_i)
@@ -1128,7 +1119,7 @@ Previously a part of standard library, Set (a collection of unique elements) was
11281119
t.dup.tag #=> nil
11291120
```
11301121
This is a [bug](https://bugs.ruby-lang.org/issues/19362).
1131-
* **Follow-ups:** [Since Ruby 3.3](3.3.html#procdup-and-clone-call-initialize_dup-and-initialize_copy), `#dup` properly invokes `#initialize_dup`
1122+
* **Follow-ups:** [3.3](3.3.html#procdup-and-clone-call-initialize_dup-and-initialize_copy): `#dup` properly invokes `#initialize_dup`.
11321123

11331124
#### `Proc#parameters`: new keyword argument `lambda: true/false`
11341125

@@ -1163,7 +1154,7 @@ Previously a part of standard library, Set (a collection of unique elements) was
11631154
11641155
#### `Method#public?`, `#protected?`, and `#private?` are removed
11651156
1166-
Predicates to check method visibility added in Ruby 3.1 were reverted.
1157+
Predicates to check method visibility [added in Ruby 3.1](3.1.html#methodunboundmethod-public-private-protected) were reverted.
11671158
11681159
* **Reason:** The new feature implementation have led to several bugs with `Method` class behavior; while investigating the root cause for those bugs, Matz have decided that method's visibility is not its inherent property, but rather a property of the module/object that owns the method, and as such, is already present in form of `Module#{private,public,protected}_instance_methods` and `Object#{private,public,protected}_methods`
11691160
* **Discussion:** [Feature #11689#note-24](https://bugs.ruby-lang.org/issues/11689#note-24)

0 commit comments

Comments
 (0)