仕事で実に5年ぶりにRuby を触ることになったので、この5年でどんなアップデートがあったのかをキャッチアップついでにまとめてみようと思う。
TL,DR
2.6.0から最新の3.2.0までリリースノートを読んでみた
2.xは2.7.xで終わり、3系になった
JIT を使った高速化や型の静的解析ができるようになった
3系ではキーワード引数と普通の引数が分けられたのが大きなBreaking change
パターンマッチやハッシュの値の省略記法など他の言語に実装されている機能が取り入れられた
Ruby のバージョンアップについて
普段Ruby を使っている人にはわざわざ書くまでもない情報だが、Ruby は毎年クリスマスにアップデートがあり、新しいMINOR(MAJOR)バージョンがリリースされる。
ref: Ruby 2.1.0 以降のセマンティックバージョニングについて
また、ノーマルメン テナンス(不具合修正)が行われるのはほぼ直近2世代、セキュリティメンテナンス (脆弱性 の修正)が行われるのは直近3世代までで、リリースから3年と3ヶ月強(リリース後3年経った翌3末)にEOLとなる。
直近のRuby Lifecycle Timelines
Ruby ブランチごとのメンテナンス状況 より引用
つまり5年間経つと5世代の更新が発生していることになり、だいぶ差があるのではないかと予想される。
ちなみに筆者が最後にRuby を触っていた2018年は2.5.xが最新であった。
リリースノートを追ってみる
2018-12-25 Ruby 2.6.0
www.ruby-lang.org
2.6で取り上げられているアップデートは、
JIT [Experimental]
RubyVM::AbstractSyntaxTree [Experimental]
主要な新機能
Kernel#yield_self の別名として then が追加
ASCII以外の大文字でも定数を定義出来るように
終端なしRange
Enumerable#chain と Enumerator#+ が追加
Proc#<< 、Proc#>> が追加
Binding#source_location の追加
Kernel#system にexception: オプションを追加
Coverage の oneshot_lines モードの追加
FileUtils#cp_lr が追加
パフォーマンスの改善
となっている。
そういえばRuby でJIT を取り入れる話やASTを出せるようになる話を聞いていたなーと懐かしく思った。
2.6でExperimentalで導入されたあとJIT がどうなったのか調べたい気持ちになった。
あと、 その他の注目すべき 2.5 からの変更点
の項目で記載されているけど、Bundlerが標準添付されるようになったとか、--ri と --rdoc オプションが変わったとかは以前からRuby を触っていた人にとっては結構印象深い変更ではないだろうか。
参考にさせていただいた記事
2019-12-25 Ruby 2.7.0
www.ruby-lang.org
2.7で取り上げられているアップデートは、
Pattern Matching [Experimental]
REPL improvement
Compaction GC
キーワード引数を通常の引数から分離
主要な新機能
番号指定パラメータ
Enumerable#tally が追加
レシーバをselfとしてprivateメソッドを呼び出すことが許容
Enumerator::Lazy#eager が追加
パフォーマンスの改善
となっている。
界隈の反応を見るに、パターンマッチングが取り入れられたというのが目玉と見て良さそう。
あと3.0に向けてキーワード引数の取り扱いに手を入れられたようだ。
リリースノートでは取り上げられていないが、個人的には全ての引数を受け取る ...
引数が追加されたのは便利そうだなぁと感じた。(ref )
def foo (...)
bar(...)
end
Ruby で親クラスのメソッドをオーバーライドして処理を追加してsuperを呼びたいときに、superがどういう引数の受け取り方をしているかいちいち調べないといけなかったが、 ...
引数を使えばそれを考えるのを省略できそう。
ちなみにRuby 2.7.0はちょうど今月(2023/03)末でEOLとなるので、今後は3系しか使えなくなる。
参考にさせていただいた記事
2020-12-25 Ruby 3.0.0
www.ruby-lang.org
3.0で取り上げられているアップデートは、
パフォーマンスの改善
Concurrency / Parallel
Ractor (experimental)
Fiber Scheduler
静的解析
その他の主要な新機能
1行パターンマッチが再設計された (experimental)
findパターンが追加 (experimental)
一行メソッド定義が書けるようになった
Hash#except が組み込みに
となっている。
Ruby2.0.0-pのリリースが2013/02/24だった ので、実に7年以上ぶりのメジャーアップデートとなった。
自分がRuby を使い始めた2013年がちょうど1.9.3から2.0.0への過度期だったなぁと懐かしい気持ちになった。
5年前時点ではRuby 3.0では型推論 が入るとか型が入るとか *1 もろもろ騒がれていたけど、最終的に静的解析に落ち着いたのかな(もしくは自分がキャッチアップできていなかっただけで最初から静的解析の話しかなかった?)
メジャーバージョンがあがってbreakingな変更はキーワード引数と通常引数の分離がよく挙げられている印象。
2.xでは雑にhashをメソッドに渡せばよかれに色々やれてたのが便利ではあったけど、正されたのね。
参考にさせていただいた記事
- Ruby 3の静的解析機能のRBS、TypeProf、Steep、Sorbetの関係についてのノート
- サンプルコードでわかる!Ruby 3.0の主な新機能と変更点 Part 2 - 新機能と変更点の総まとめ
- jnchitoさんの記事がQiitaからZennに移行されましたね
- アプリケーションをRuby3にあげるときにやること
2021-12-25 Ruby 3.1.0
www.ruby-lang.org
3.1で取り上げられているアップデートは、
YJIT: New experimental in-process JIT compiler
debug gem: 新しいデバッガ
error_highlight: バックトレース中の詳細なエラー位置表示
IRB のオートコンプリートとドキュメント表示
その他の主要な新機能
ハッシュリテラル やキーワード引数の値が省略可能に
パターンマッチ中のピン演算子 に任意の式を書けるように
一行パターンマッチで括弧が省略できるように
RBS 、TypeProfのアップデート
となっている。
2.6でJIT が取り入れられて以来Ruby 3×3 として高速化が試みられてきたけど、Rails のようなアプリケーションの高速化は達成できていなかったのがここに来て改善できたということらしい。
ここに来て急にデバッグ 周りの改善が入ったのも浦島的には謎。何があったんだろう?
個人的には ハッシュリテラルやキーワード引数の値が省略可能に
なったのがとんでもない変更だと思う。Rubyist たちはこの無駄な文字列の繰り返しを無限に書き続けてきたのではなかろうか。
x = 1
y = 2
z = {x :, y :}
def foo (x :, y :)
end
ただ、バージョンによって動かなくなっちゃうと思うので各種Gemではまだこの書き方は浸透させられない気もする。
2022-12-25 Ruby 3.2.0
www.ruby-lang.org
ここでようやく直近のアップデートまで来た。
3.2で取り上げられているアップデートは、
WASIベースのWebAssemblyサポート
実用段階になったYJIT
ReDoSに対するRegexp の改善
その他の主要な新機能
SyntaxSuggest
ErrorHighlight
匿名の可変長引数と可変長キーワード引数が引数としても使えるように
他
新たなコアクラス Data が追加
ここにきてWebAssemblyかーと思ったけど、WebAssemblyをマルチプラットフォーム な実行環境として使うっていう試みはRuby じゃないどこかで確かに見た気がする。
新しいコアクラスのDataは今までActiveModelを使って実装してた値を持つだけのクラスを簡単に用意できそうだなっていう印象。今までもStructでできたと思うけどimmutableだったりするらしいので、環境変数 やらどこかやらからロードした設定値を持っとくだけのクラスとかを作るのに使えそう。
あと Dir.exists?
と File.exists?
が削除されたってマジ?と思ったらだいぶ前からDir.exist?
と File.exist?
使えっていうことになってたのね。
チケット見たら3.0.0で消したら?って提案されていたのに3.2になったぽい。多分それくらい忘れられてたってことなのかな。
浦島的まとめ
キーワード引数の取り扱いについては認識を改める必要がある
JIT で高速化されて、実用的なレベルに達した
型については静的解析ができるようになった
ということで思ったより大きな変化は正直なかったのかなと思う。
もろもろ全然変わっていて以前の知識じゃついていけないということはなさそう。
このあたりはPython2 -> 3 が人類にもたらした後方互換 性を諦めると色々終わるという知見がエンジニアの脳裏に刻まれているんだろうなって気がする 笑