Skip to content

Commit 4d7c81b

Browse files
committed
Add Ruby Evolution section
1 parent e36ac55 commit 4d7c81b

20 files changed

Lines changed: 2081 additions & 54 deletions

2.4.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ prev: 2.5
1515
-->
1616

1717
* **Released at:** Dec 25, 2016 (<a class="github" href="https://github.com/ruby/ruby/blob/trunk/doc/NEWS-2.4.0">NEWS</a> file)
18-
* **Status (as of Jan 11, 2022):** EOL, latest is 2.4.10
18+
* **Status (as of Feb 16, 2022):** EOL, latest is 2.4.10
1919
* **This document first published:** Oct 14, 2019
20-
* **Last change to this document:** Jan 11, 2022
20+
* **Last change to this document:** Feb 16, 2022
2121

2222
## Highlights[](#highlights)
2323

2.5.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ prev: 2.6
1515
-->
1616

1717
* **Released at:** Dec 25, 2017 (<a class="github" href="https://github.com/ruby/ruby/blob/trunk/doc/NEWS-2.5.0">NEWS</a> file)
18-
* **Status (as of Jan 11, 2022):** EOL, latest is 2.5.9
18+
* **Status (as of Jul 09, 2022):** EOL, latest is 2.5.9
1919
* **This document first published:** Jun 6, 2019
20-
* **Last change to this document:** Jan 11, 2022
20+
* **Last change to this document:** Jul 09, 2022
2121

2222
## Highlights[](#highlights)
2323

@@ -317,6 +317,7 @@ Previously, those methods raised `TypeError` on arguments that can't be coerced
317317

318318
* **Discussion:** <a class="tracker feature" href="https://bugs.ruby-lang.org/issues/13712">Feature #13712</a>
319319
* **Documentation:** <a class="ruby-doc" href="https://ruby-doc.org/core-2.6/String.html#method-i-start_with-3F"><code>String#start_with?</code></a> (introduced in 2.5, but documented in 2.6)
320+
* **Note:** While looking a symmetric method, `#end_with?` does **not** support regexp; the possibility was discussed in the feature proposal and it was general agreement that the behavior should be symmetric, but eventually the implementation turned out to be too hard.
320321

321322
#### `String#-@` optimized for memory preserving[](#string--optimized-for-memory-preserving)
322323

2.6.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ next: 2.5
77
# Ruby 2.6
88

99
* **Released at:** Dec 25, 2018 (<a class="github" href="https://github.com/ruby/ruby/blob/ruby_2_6/NEWS">NEWS</a> file)
10-
* **Status (as of Jan 11, 2022):** Security maintenance, latest is 2.6.9
10+
* **Status (as of Jul 09, 2022):** Security maintenance, latest is 2.6.9
1111
* **This document first published:** Dec 29, 2018
12-
* **Last change to this document:** Jan 11, 2022
12+
* **Last change to this document:** Jul 09, 2022
1313

1414
> **Note:** As already explained in [Introduction](README.md), this site is dedicated to changes in the **language**, not the **implementation**, therefore the list below lacks mentions of lots of important optimization introduced in 2.6, including the whole JIT big thing. That's not because they are not important, just because this site's goals are different.
1515
@@ -211,12 +211,13 @@ The concept of a "timezone object" is introduced for various `Time` methods. Rub
211211
* **Reason:** Named timezones are more complicated than just "offset from UTC". Going over DST date, or between different years in country history, time could have the same timezone, but different UTC offset.
212212
* **Code:**
213213
```ruby
214-
require 'tzinfo'
215-
tz = TZInfo::Timezone.get('America/New_York')
216-
t = Time.new(2018, 6, 1, 0, 0, 0, tz)
217-
t.utc_offset # => -14400, -4 hours
218-
t += 6 * 30 * 24 * 60 * 60 # + 6 months
219-
t.utc_offset # => -18000, -5 hours
214+
zone = TZInfo::Timezone.get('America/New_York')
215+
time = Time.new(2018, 6, 1, 0, 0, 0, zone)
216+
time.zone # => #<TZInfo::DataTimezone: America/New_York>
217+
time.strftime('%H:%M %Z') # => "00:00 EDT"
218+
time.utc_offset # => -14400 = -4 hours
219+
time += 180 * 24*60*60 # + 180 days, summery->winter transition
220+
time.utc_offset # => -18000, -5 hours -- daylight saving handled by timezone
220221
```
221222
* **Follow-up:** In Ruby 3.1, the new ways for handier constructing time with timezones [were introduced](3.1.html#in-parameter-for-constructing-time).
222223

2.7.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ next: 2.6
77
# Ruby 2.7
88

99
* **Released at:** Dec 25, 2019 (<a class="github" href="https://github.com/ruby/ruby/blob/ruby_2_7/NEWS">NEWS</a> file)
10-
* **Status (as of Jan 11, 2022):** 2.7.5 is current _stable_
10+
* **Status (as of Feb 16, 2022):** 2.7.5 is current _stable_
1111
* **This document first published:** Dec 27, 2019
12-
* **Last change to this document:** Jan 11, 2022
12+
* **Last change to this document:** Feb 16, 2022
1313

1414
<!-- TODO: all links to docs should be replaced with /2.7.0/ suffix instead of /master/ when 2.7.0 would be published -->
1515

3.0.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ next: 2.7
77
# Ruby 3.0
88

99
* **Released at:** Dec 25, 2020 (<a class="github" href="https://github.com/ruby/ruby/blob/ruby_3_0/NEWS.md">NEWS.md</a> file)
10-
* **Status (as of Jan 11, 2022):** 3.0.3 is current _stable_
10+
* **Status (as of Jun 19, 2022):** 3.0.3 is current _stable_
1111
* **This document first published:** Dec 25, 2020
12-
* **Last change to this document:** Jan 11, 2022
12+
* **Last change to this document:** Jun 19, 2022
1313

1414
## Highlights[](#highlights)
1515

@@ -80,7 +80,7 @@ Just a leftover from the separation of keyword arguments.
8080

8181
* **Reason:** Argument forwarding, when [introduced in 2.7](2.7.html#keyword-argument-related-changes), was able to forward only all-or-nothing. It turned out to be not enough. One of the important usages for leading arguments are cases like `method_missing` and other DSL-defined methods that need to pass to the nested method `:some_symbol` + all of the original arguments.
8282
* **Discussion:** <a class="tracker feature" href="https://bugs.ruby-lang.org/issues/16378">Feature #16378</a>
83-
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/master/doc/syntax/methods_rdoc.html#label-Argument+forwarding"><code>doc/syntax/methods.rdoc</code></a> _<small>(the link is to a `master` version, docs were merged post 3.0 release)</small>_
83+
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/master/syntax/methods_rdoc.html#label-Argument+forwarding"><code>doc/syntax/methods.rdoc</code></a> _<small>(the link is to a `master` version, docs were merged post 3.0 release)</small>_
8484
* **Code:**
8585
```ruby
8686
def request(method, url, headers: {})
@@ -144,7 +144,7 @@ Methods of exactly one statement now can be defined with syntax `def method() =
144144
```
145145

146146
* **Discussion:** <a class="tracker feature" href="https://bugs.ruby-lang.org/issues/16746">Feature #16746</a>
147-
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/master/doc/syntax/methods_rdoc.html"><code>doc/syntax/methods.rdoc</code></a> _<small>(the link is to a `master` version, docs were merged post 3.0 release)</small>_
147+
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/master/syntax/methods_rdoc.html"><code>doc/syntax/methods.rdoc</code></a> _<small>(the link is to a `master` version, docs were merged post 3.0 release)</small>_
148148
* **Code:**
149149
```ruby
150150
def dbg = puts("DBG: #{caller.first}")
@@ -224,7 +224,7 @@ Methods of exactly one statement now can be defined with syntax `def method() =
224224

225225
* **Reason:** This is an interesting one. Two facts were discussed between 2.7 and 3.0: the fact that in most of the other languages one-line pattern matching has a different order (`<pattern> <operator> <data>`) than introduced in Ruby 2.7 (`<data> in <pattern>`); and the idea of "rightward assignment operator" `=>` for more natural chaining. And then, at some point, ideas converged most fruitfully.
226226
* **Discussion:** <a class="tracker feature" href="https://bugs.ruby-lang.org/issues/17260">Feature #17260</a> (main pattern matching tracking ticket), <a class="tracker feature" href="https://bugs.ruby-lang.org/issues/16670">Feature #16670</a> (reverse order), <a class="tracker feature" href="https://bugs.ruby-lang.org/issues/15921">Feature #15921</a> (standalone rightward assignment operator), <a class="tracker feature" href="https://bugs.ruby-lang.org/issues/15799">Feature #15799</a> (abandoned "pipeline operator" idea, in discussion of which "rightward assignment" was born)
227-
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.0.0/doc/syntax/pattern_matching_rdoc.html"><code>doc/syntax/pattern_matching.rdoc</code></a>
227+
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.0.0/syntax/pattern_matching_rdoc.html"><code>doc/syntax/pattern_matching.rdoc</code></a>
228228
* **Code:**
229229
```ruby
230230
# match and unpack:
@@ -269,7 +269,7 @@ After the change described above, `in` was reintroduced to return `true`/`false`
269269

270270
* **Reason:** The new meaning allows pattern matching to be more tightly integrated with other constructs in the control flow, like iteration and regular conditions.
271271
* **Discussion:** <a class="tracker feature" href="https://bugs.ruby-lang.org/issues/17371">Feature #17371</a>
272-
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.0.0/doc/syntax/pattern_matching_rdoc.html"><code>doc/syntax/pattern_matching.rdoc</code></a>
272+
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.0.0/syntax/pattern_matching_rdoc.html"><code>doc/syntax/pattern_matching.rdoc</code></a>
273273
* **Code:**
274274
```ruby
275275
user = {role: 'admin', login: 'matz'}
@@ -300,7 +300,7 @@ After the change described above, `in` was reintroduced to return `true`/`false`
300300
Pattern matching now supports "find patterns", with several splats in them.
301301

302302
* **Discussion:** <a class="tracker feature" href="https://bugs.ruby-lang.org/issues/16828">Feature #16828</a>
303-
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.0.0/doc/syntax/pattern_matching_rdoc.html"><code>doc/syntax/pattern_matching.rdoc</code></a>
303+
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.0.0/syntax/pattern_matching_rdoc.html"><code>doc/syntax/pattern_matching.rdoc</code></a>
304304
* **Code:**
305305
```ruby
306306
users = [
@@ -741,7 +741,7 @@ The "reverse" order of the backtrace (call stack printed starting from the outer
741741
742742
* **Reason:** The idea of `frozen-string-literal` pragma is to avoid unnecessary allocations, when the same `"string"` repeated in the code called multiple times; but if the string is constructed dynamically with interpolation, there would be no point (it is hard to predict that allocations would be avoided, as the string can be different each time); it also breaks the "intuitive" feeling that the string is dynamic.
743743
* **Discussion:** <a class="tracker feature" href="https://bugs.ruby-lang.org/issues/17104">Feature #17104</a>
744-
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.0.0/doc/syntax/comments_rdoc.html#label-frozen_string_literal+Directive"><code>doc/syntax/comments.rdoc</code></a>
744+
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.0.0/syntax/comments_rdoc.html#label-frozen_string_literal+Directive"><code>doc/syntax/comments.rdoc</code></a>
745745
* **Code:**
746746
```ruby
747747
# frozen-string-literal: true

3.1.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ next: 3.0
77
# Ruby 3.1
88

99
* **Released at:** Dec 25, 2021 (<a class="github" href="https://github.com/ruby/ruby/blob/ruby_3_1/NEWS.md">NEWS.md</a> file)
10-
* **Status (as of Jan 11, 2022):** 3.1.0 is current _stable_
10+
* **Status (as of Jun 19, 2022):** 3.1.0 is current _stable_
1111
* **This document first published:** Jan 5, 2022
12-
* **Last change to this document:** Jan 11, 2022
12+
* **Last change to this document:** Jun 19, 2022
1313

1414
> **Note:** As already explained in [Introduction](README.md), this site is dedicated to changes in the **language**, not the **implementation**, therefore the list below lacks mentions of lots of important optimization introduced in 3.1, including a new JIT named YJIT. That's not because they are not important, just because this site's goals are different.
1515
@@ -34,7 +34,7 @@ In hash literals and method calls, `x:` is now a shortcut for `x: x`—take hash
3434

3535
* **Reason:**
3636
* **Discussion:** <a class="tracker feature" href="https://bugs.ruby-lang.org/issues/14579">Feature #14579</a>
37-
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.1/doc/syntax/literals_rdoc.html#label-Hash+Literals">doc/syntax/literals.rdoc#Hash Literals</a>, <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.1/doc/syntax/methods_rdoc.html#label-Keyword+Arguments">doc/methods.rdoc#Keyword Arguments</a>, <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.1/Hash.html"><code>Hash</code></a>
37+
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.1/syntax/literals_rdoc.html#label-Hash+Literals">doc/syntax/literals.rdoc#Hash Literals</a>, <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.1/syntax/methods_rdoc.html#label-Keyword+Arguments">doc/methods.rdoc#Keyword Arguments</a>, <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.1/Hash.html"><code>Hash</code></a>
3838
* **Code:**
3939
```ruby
4040
x, y = 100, 200
@@ -93,7 +93,7 @@ In hash literals and method calls, `x:` is now a shortcut for `x: x`—take hash
9393

9494
* **Reason:** When endless methods were introduced in 3.0, this syntax (named "command syntax" internally) wasn't allowed; but it was not a deliberate decision, and rather a side-effect of a parser complexity. During development of 3.1, the workaround was found to make code more consistent and refactoring from multi-line to single-line methods easier.
9595
* **Discussion:** <a class="tracker feature" href="https://bugs.ruby-lang.org/issues/17398">Feature #17398</a>
96-
* **Documentation:** — (<a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.1/doc/syntax/methods_rdoc.html"><code>doc/syntax/methods.rdoc</code></a> doesn't mention new or old behavior.)
96+
* **Documentation:** — (<a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.1/syntax/methods_rdoc.html"><code>doc/syntax/methods.rdoc</code></a> doesn't mention new or old behavior.)
9797
* **Code:**
9898
```ruby
9999
def log(msg) = puts "#{Time.now}: #{msg}"
@@ -107,7 +107,7 @@ If method uses its block argument only to pass to another method, it can be mark
107107
108108
* **Reason:** The initial proposal for the feature is 6-year old and focused on avoiding intermediate blocks object allocation on block forwarding. It was considered redundant when block forwarding was optimized in Ruby 2.5; but then the core team decided it is actually a nice and unambiguous shortcut for methods that just pass the block further. As bloc argument is frequently called just `block`, the absence of the name doesn't affect readability.
109109
* **Discussion:** <a class="tracker feature" href="https://bugs.ruby-lang.org/issues/11256">Feature #11256</a>
110-
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.1/doc/syntax/methods_rdoc.html#label-Block+Argument">doc/syntax/methods.rdoc#Block Argument</a>
110+
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.1/syntax/methods_rdoc.html#label-Block+Argument">doc/syntax/methods.rdoc#Block Argument</a>
111111
* **Code:**
112112
```ruby
113113
def logged_open(filename, &)
@@ -151,7 +151,7 @@ If method uses its block argument only to pass to another method, it can be mark
151151
On the initial implementation of the pattern matching, the only patterns that could've been used in matching expression were constants, literals and pinned local variables. Since 3.1, any kind of statement can be a pattern, with extended functionality of the `^` pin operator.
152152

153153
* **Discussion:** <a class="tracker feature" href="https://bugs.ruby-lang.org/issues/17411">Feature #17411</a> (pinning expressions), <a class="tracker feature" href="https://bugs.ruby-lang.org/issues/17724">Feature #17724</a> (pinning class/global variables)
154-
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.1/doc/syntax/pattern_matching_rdoc.html#label-Variable+pinning">doc/syntax/pattern_matching.rdoc#Variable pinning</a>
154+
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.1/syntax/pattern_matching_rdoc.html#label-Variable+pinning">doc/syntax/pattern_matching.rdoc#Variable pinning</a>
155155
* **Code:**
156156
```ruby
157157
# In Ruby 3.0, this was possible:
@@ -178,7 +178,7 @@ On the initial implementation of the pattern matching, the only patterns that co
178178
#### Parentheses can be omitted in one-line pattern matching.[](#parentheses-can-be-omitted-in-one-line-pattern-matching)
179179

180180
* **Discussion:** <a class="tracker feature" href="https://bugs.ruby-lang.org/issues/16182">Feature #16182</a>
181-
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.1/doc/syntax/pattern_matching_rdoc.html#label-Patterns"><code>doc/syntax/pattern_matching.rdoc#Patterns</code></a>
181+
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.1/syntax/pattern_matching_rdoc.html#label-Patterns"><code>doc/syntax/pattern_matching.rdoc#Patterns</code></a>
182182
* **Code:**
183183
```ruby
184184
[0, 1] => _, x
@@ -1195,7 +1195,7 @@ Since being added [in 2.6](2.6.html#rubyvmresolve_feature_path) (then named `Rub
11951195

11961196
* **Reason:** It was argued that raising `LoadError` makes method looks like it has a side effect instead of just being a query method, and makes it inconvenient to use.
11971197
* **Discussion:** <a class="tracker feature" href="https://bugs.ruby-lang.org/issues/16043">Feature #16043</a>
1198-
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.1/doc/globals_rdoc.html"><code>doc/globals.rdoc</code></a>
1198+
* **Documentation:** <a class="ruby-doc" href="https://docs.ruby-lang.org/en/3.1/globals_rdoc.html"><code>doc/globals.rdoc</code></a>
11991199
* **Code:**
12001200
```ruby
12011201
$LOAD_PATH.resolve_feature_path('garbage111')

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ source 'https://rubygems.org'
33
gem 'rake'
44
gem 'memoist'
55
gem 'github-pages', group: :jekyll_plugins
6+
gem 'kramdown'

Gemfile.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ PLATFORMS
283283

284284
DEPENDENCIES
285285
github-pages
286+
kramdown
286287
memoist
287288
rake
288289

Rakefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ file '_data/book.yml' => FileList['_src/*.md'] do |t|
1313
File.write(t.name, Util.deep_stringify_keys(chapters: chapters).to_yaml)
1414
end
1515

16-
rule /^\d+\.\d+\.md$/ => ->(s) { "_src/#{s}" } do |t|
16+
rule /^(\d+\.\d+|evolution)\.md$/ => ->(s) { "_src/#{s}" } do |t|
1717
from, to = t.prerequisites.first, t.name
1818

1919
puts "Rendering #{from} => #{to}"
2020
File.write(to, Render.(from))
2121
end
2222

2323
desc 'Convert file contents from source to target (prettify)'
24-
task contents: [*('2.4'..'2.7'), *('3.0'..'3.1')].map(&'%s.md'.method(:%))
24+
task contents: ['evolution', *('2.4'..'2.7'), *('3.0'..'3.1')].map(&'%s.md'.method(:%))
2525

2626
desc 'Render TOC for the changelog "book"'
2727
task toc: '_data/book.yml'

0 commit comments

Comments
 (0)