Ruby Kaigi 2020 Takeout の Keynote が Youtube で閲覧可能になったので、それを見て Ruby3 の内容をざっくりまとめた自分用メモです。

ちなみに、Ruby3の登場は2020年12月25日を予定しているようです。

互換性を大事にしたリリースになる

  • キーノートの中で何度も繰り返し言われいて、枕の中でも力を入れて話していた部分
  • コミュニティ分断を引き起こしてしまった経験を踏まえて、ドラスティックな変更や挑戦的な変更は入ってこない様子

性能と生産性の改善

高速であることを目指す

  • Ruby2.4から搭載されているJITコンパイラに磨きをかけて、ある種のベンチマークではRuby2.0に比べて3倍の高速化をほぼ達成できている
    • 3x3 Rubyとして目指してきた目標を踏まえた話だけど、Rubyコミュニティがそこまでこれに期待していたかは個人的には疑問が残る感じ
  • Railsは早くならないが、遅くならない程度には作り込めている
    • 結局Railsアプリが早くならないことにはRuby自体の高速化があってもRuby最大の利用者クラスタに対するインパクトは小さいのかなと思う
    • もうひと頑張りできるかな?ぐらいの感じらしいので、出る頃の状況に期待

コンカレンシー(並行実行)

  • 非同期のI/O Fiber
    • I/Oがボトルネックになっているアプリケーションのための機能
    • 非同期のI/OをFiberを使って実現することでI/Oの多重化を行う
    • awaitとかasyncとかつけなくてもいいのは、Rubyらしさかなと思う
    • マルチコアの活用にはつながらないが、I/Oヘビーなアプリケーションでは性能向上が見込める
  • Ractor
    • ちょっと前にGuildという概念で紹介されていた元の同じ
    • Ruby ACTORでRactor
      • Erlangとかで取り入れられているActorモデルのACTORかな
    • 分離されたオブジェクトスペース同士がチャンネルを通じたコミュニケーションを行うモデルで並行実行を行う
    • 分離されたオブジェクトスペース同士の間では状態の共有がない
    • Ractorのオブジェクトスペース同士でやり取りできるオブジェクトには制限が設けられている(状態共有しないので)
      • イミュータブルなオブジェクト(数値とかシンボル)
      • frozenな文字列はやり取りできるが、普通の文字列とか普通のオブジェクトは共有できない
      • Deeply frozenなオブジェクト
        • あるオブジェクトから指されているオブジェクトを再起的にみて、全てがfrozenされている状態をDeeply frozenとして新たに定義する
      • ClassとModule
        • Rubyではオープンクラスとか、ClassもModuleもイミュータブルではない
        • ロックしてやり取りするような機構が入ることになるので、若干遅くなる
    • Ractor間ではGILがない(Ractor内ではGILがある)

正しいコードを書くための支援機能(静的型チェック)

  • RBS (Ruby Signature)
    • typescript のd.tsにあたるようなもの
    • RubyっぽいがRubyとは違う文法の型定義言語で書く
    • コアライブラリの方を表現したRBSが同梱される予定
    • 型チェッカーやIDEが賢くなるはず
  • Type Profilerが同梱される
    • 簡単な型チェッカー
    • ユーザのアプリケーションのRBS生成も支援する

新しい文甫

  • パターンマッチング(2.7から)
case JSON.parse(json, symbolize_names: true)
in {name: "サザエ", children: [*, {name: "タラヲ", age: age}, *]}
  p "サザエ、息子は#{age}才"
in _
  p "サザエではない"
end
  • 右代入
    • メソッドチェーンの結果を(思考の流れそのままで)変数に代入できるような記法
(1..100).map{|x| rand(x)}.sort.reverse.take(10) => top_ten # メソッドチェーンの結果得られた値をtop_tenに代入する
  • ナンバードブロックパラメータ
    • ブロックに渡ってくるパラメータを、アンダーバー(_)と数字の組み合わせで表現して記述できる省略記法
[2,4,6].map{_1 * 3} # 変数xとか用意しなくてもmapのブロックに渡される1番目の引数を_1で参照できる
#> [6, 12, 18]

Ruby3の期間で起こること

  • サポートツールに注力する
    • lintとか、Language Server Protocolを活用したツールとかをもっと充実させる
    • よりよいサポートツールが生まれる土壌を作る
  • 言語そのものを変えなくても生産性が向上するようなツールを充実させられる土壌を作る
  • Rubyプログラマの生産性がどんどん上がるようにする
  • 高速化をより求めていく
    • より軽いJITコンパイラを使って、マルチレイヤーでのJITを実現するとか
    • V8とかのJITの仕組みとかも参考にして改善していく
  • 追加のアイディアとして
    • Rubyの中にコア言語みたいな、サブセットを定義して、その記法で書かれている範囲であれば高速に動かせるとか、そんなアイディアが披露された