RubyKaigi 2026初参加: メカMatzとヒューマンインテリジェンスと個人的教訓
RubyKaigi 2026 参加メモ
早く書かないと忘れていくから。まずは取っていたメモをダンプ。ちょっと英語聞き間違えたりなどして間違えている部分があれば、コメントなどしていただけるとありがたいです。
先に個人的に得た教訓
取る宿はよく考えた方がいい
宿の予約時、社内のチャットに『ここにしようと思います』と投下したら、『そこやめたほうがいい』と @kenchan と いかるがさんにアドバイス受けた。アドバイス通りに会場近くの宿を取ったが、大正解だった。会期ごとに異なるかもしれないが、開催地に詳しいRubyistに聞いた方が良い。
各社のドリンクアップにはなるたけ参加申し込みしておいた方が良い
私は何も予約できてなくて、当日キャンセル待ちした。精神的に負荷が高いのでちゃんと事前に駆け込んでおくこと。
また、知り合いがいなくてもなんとかなる。絶対行けば楽しい。最近やってる仕事の話とか間違いなく盛り上がる。何かしら共通の課題感とかあるんじゃなかろうか。あとシンプルに全国に知り合いができるのが嬉しいよ。
手元でPicoRubyとかmrubyとかcrubyを動かすか、予習しておくともっと楽しい
じゃないとついていけないトピックが多いかも。
全体を通しての所感
個別のセッションで得た技術トピックはそれぞれ難しいが興味深く、もっとRubyについて深く理解したいと意欲させられるものばかりだった。そして何よりRubyを今まさに作っている人たちがこれほどいるんだという感動があった。
そして、Day3 の「メカMatz」のジョークが象徴的だったが、Rubyに対する情熱や願い、夢といったものは人間でなければ語り得ない(少なくとも今のところは)こと。コミッターの半数以上がAIを使ってコードを書く時代になっても、「Rubyをこういう言語にしたい」と言葉にして引っ張っていくのは結局のところ人間であること。
また、その情熱を引き継いで言語を育てていくのは、今ステージに上がっているコミッターたちだけではないこと。今ステージに上がっていない未来のRubyコミッター、つまり自分も含めた聴衆こそが、これからのRubyを作っていく側であるということ。
「Rubyが好き」と口で言うだけではなく、少しずつでも自分が貢献できる場所を見つけて、実際に手を動かしていく。そうやってみんなでRubyを今後も育てていきたいと思った。
(そのために避けて通れないのは CRubyへの理解 だなと痛感した、、)
この会を作り上げてくださった皆さん、参加者の皆さん、ありがとうございました!また来年👋
Day1
1. Keynote: Ruby Box(旧 namespace)
概要
かつて namespace という名前で議論されてきた機能が Ruby::Box にリネームされて登場。Ruby::Box というAPIでアクセスする。一言でいうと「同一プロセス内に複数の隔離空間を作れる仕組み」で、モンキーパッチの影響範囲を切り離したり、同一プロセス内でブルーグリーンデプロイ的な切り替えをやったりできる。
キーポイント
-
何が嬉しいか
- モンキーパッチの影響範囲を別空間内(同一プロセス)で閉じ込められる
- 同一プロセス内でBGデプロイ的な置き換えができる
- モチベーションのひとつにAWS Lambdaがある。Lambdaは同じプロセス内ではグローバルに状態が共有されてしまうので、その分離欲求を満たす
-
実装の構成要素(ingredients)
- Current box management / detection: 「いま自分はどのboxにいるのか」を管理し検出する仕組み。なぜ管理しないといけないかが議論の起点
-
Control frame と Environment:
- envのVALUEは逆順で読む
- control frameとenvはそれぞれ左端・右端から伸びていき、いつか衝突する。それがstack overflow
-
解決の効くタイミング
-
requireした時点ではメソッドの中身は見ない(参照解決を遅延させる) - メソッドの中身を見るのは呼ばれたときだけ
- 「一番近いLOCALからBOXを特定する」というルールでboxを決定する
- boxは
require/load/require_relativeで切り替わる
-
-
背景
- Tagomoris / LFA の系譜
- shioyamaさんからの着想
2. Test Impact Analysis (TIA)
概要
変更箇所に依存するテストだけを選んで実行する Test Impact Analysis の話。Ruby のテスト実行で「どのテストがどのコードに触れたか」をどう取るか、計測コストとの両立をどう図るかが軸。
3. Portable and Fast(Red Data Tools / Red Datasets)
概要
Red Datasets gemのテストが、対応データセット増加に伴って遅くなっていた問題への取り組み。「並列実行」を、portability(OS・Rubyバージョンを問わず動くこと)と fastness(CPUを遊ばせない)の両立という軸で設計し直した話。
キーポイント
-
最初にやるべきは「個別テストの高速化」
- 並列化の前に、ボトルネックになる遅いテストを潰す
- 一番効いた手は「(不要なテストを)消す!!」
-
並列化の選択肢
- スレッド
- マルチプロセス(今日の話題)
- 次のステップとして Ractor
-
マルチプロセスの設計課題
-
Portable であるために
-
Kernel.#forkは使えない環境がある -
Kernel.#spawnはオーバーヘッドが大きいが portable - 親プロセスの状態を子から参照できる必要がある
- 最近のRubyは「親の状態を共有する系」を gem に分離していく流れ。DRb は使わない方針。後方互換性は重視
-
-
Fast であるために
- プロセスを暇させない
- CPU1がbusyでCPU2がidleなら仕事を回したい
- Fixture問題: 「各テスト前後でsetup/teardownはオーバーヘッド大」「まとめてsetup→複数テスト→teardownはバランスが悪い」
-
Portable であるために
-
解決策
- 状態の再現: spawnは真っさらな環境を作る。ベースディレクトリを決め打ちして、コマンドライン引数経由で子プロセスに渡す
-
IPCの選択肢
-
Pipe:
Marshal.dump/Marshal.load、Thread::Queue的な共有パイプ。実行結果は親子間で1バイトでやり取り - TCP/IP socket
- Unix domain socket
-
Pipe:
-
暇させない設計
- Consumerを暇にしないのが目標
-
Push型(producerが配る)よりPull型(consumerが取りに行く)が良い
- Producerは誰が暇しているか分からないため
- Ractor はその先のステップとして視野
Day2
1. Keynote: Twenty Years of JRuby(headius)
概要
Charles Nutter(headius)による、JRubyの20年を振り返るキーノート。1996年のミネソタ大時代のJava体験から始まり、RubyConf 2004で JRuby と出会い、reborn させ、2006年に Rails を動かし……という個人史と、JRubyが現在どこまで来ていて、これから何を目指すかというロードマップ。並行性とアロケーション速度の比較で、JRubyの現在地を数字で見せてくれた。
キーポイント
-
来歴
- TRON、1996-1998 ミネソタ大学(Java applets / web-based)、1998-2002 senior Java
- RubyConf 2004(Washington): 65人の参加者、廊下でrakeやrubygemsをハック、Pickaxe(PragProg)が出た会、「Ko1に聞け」、そこでJRubyの話が出た
- JRuby is reborn: 2004は活動が低調、開発者も少なかった
- 2006: JRuby on Rails が動いた(ものすごく遅かった!)。JavaOne 2006で発表
- RubyKaigi 2007、JRubyKaigi 2010
-
Hard work
- String と Regexp はスクラッチで実装し直した
-
JITコンパイラ
- 2008: JRuby向けにJITコンパイラ実装。Rubyとして初めての native JIT
-
Fibers
- 2007にRubyがFiberを導入。JRubyはネイティブスレッドで実装するしかなかった(重い)
- JVM language としてのJRuby
-
Object.new アロケーションレート
- CRuby 3.4: 1x
- CRuby(別計測): 1.46x
- JRuby: 24.6x
-
Garbage Collector
- JVMはGCの選択肢が一番強い
-
Concurrency
- Ractor: Rubyに並行性を持ち込んだが、VM側の課題が多い/使いにくい(immutability、C拡張との整合)
- JRubyのスレッドはすでに100%パラレル: スレッド/共有メモリのオーバーヘッドが低く、使いやすい
- ベンチマーク(Thread vs Ractor)
- CRuby threads: 1.6x
- CRuby ractors: 3.7x
- JRuby threads: 6x(20コアなら20x)
- ユーザー事例: Logstash、easy BI
-
Future
-
JRuby 10.1: システム全体でオブジェクトを小さくする / スループット改善
- 構成要素: padding / ivars / class / lock
- JRuby 10.0
-
JVMの改善も効く
- Compressed pointers
- Compact object headers(JVMオブジェクト全体のサイズを縮める)
-
Array.new(1000)のメモリサイズ- CRuby 4.0: 8040 bytes
- JRuby: 40xx bytes(大幅に小さい)
-
Object.newが最も顕著な例 - Beyond 10.1: Advanced shaping
-
JRuby 10.1: システム全体でオブジェクトを小さくする / スループット改善
2. From Formal Specification to Property Based Test(ohbarye)
概要
「仕様が正しいか」「実装が正しいか」を分けて考えるところからスタートし、Formal Methods → Formal Specification → Property Based Test → Implementation という流れを直結させる試み。spec-to-pbt というライブラリを通じて、formal spec から PBT を半自動生成するアプローチを示した。
キーポイント
-
モチベーション
- 「仕様が正しいか/実装が正しいか」は別問題
- Formal methods: その手前に formal specification がある
-
Property Based Testing (PBT) とは
- SUT(テスト対象)が「この性質を満たす」と示すもの
- RuboCop は example based testing: 個別の例で検証する方式 → 漏れが起きうる
- PBTは多数の値をランダム生成し、success / fail に振り分けて性質を確認する → 多様な入力を与えられる
- ジャンル
- Stateless
- Stateful(spec-to-pbt は主にこちら寄り?)
-
どう繋ぐか(How we combine)
- 流れ: Human → Formal Spec → Property Based Test → Implementation
- ライブラリ: spec-to-pbt
- 設計判断
- Scaffold, not compiling: 完成品を生成するのではなく足場を出す
- Regeneration: 再生成可能であること
- Fix upstream, not workaround: 下流で回避するのではなく上流を直す
- Pattern analysis and promotion: パターンを抽出して昇格させる
- formal spec、property based testing が何故重要なのかを最後にもう一度
3. No Types Needed, Just callable method check(@dak2)
概要
「AI時代において、もはや型は要らないのでは?必要なのは『そのメソッドが呼べるか』という確認だけでは?」というチャレンジングな問いから始まる発表。method-ray という gem を実装し、I/F は Ruby、コアロジックは Rust で書いている。
キーポイント
-
問題提起
- AI時代では、メソッドが callable であることだけ確認できればいいかもしれない
-
型の便益(おさらい)
- RBS::Inline
-
型のエコシステム
- RBS / RBS::Inline / Steep / TypeProf
- 最近 RBS に inline が入った
- Types as contract という見方
-
method-ray gem
- メソッドが callable かどうかをチェックする
- NoMethodError を防ぐだけに集中する
- インターフェースは Ruby、コアロジックは Rust
4. A Faster FFI(tenderlove)
概要
tenderlove による FFI(Foreign Function Interface)高速化の話。libffi ベースのRuby FFIはパフォーマンスが良くないという問題に対して、JITコンパイル(FJIT)と新しいAPI(ZJIT API + FFX)を使い、最終的に「Rubyを書いてCより速い」を狙う、という壮大な提案。
キーポイント
-
FFIとは
- Foreign Function Interface — 外部関数を呼び出す仕組み
-
libffiの gem - FFI is idea, not library: 「FFI」は概念であってライブラリ単体ではない
- Native拡張はなるべく避けたい(GCの問題を含めて)
-
なぜFFIに手を入れるのか
- 既存のFFIのパフォーマンスが良くない
- 原因: Ruby → C拡張への呼び出しコスト
- Faster FFI for Ruby
-
JITコンパイル
- FJIT を作ってみた
-
Ruby自身が FFI をサポートするという方向性
- ZJIT API + FFX(github.com/tenderlove/ffx)
- CRuby上でCに変換する
- JITコンパイラとして動く
- Rubyを書いてCより速い が実現可能になる
Day3
1. Ruby Committers and the World
概要
Ruby Dev Meetingを公開で開催する恒例パネル。新規コミッター紹介、コアな機能提案、ガバナンスと後継者問題、AIの活用、setjmp/longjmpの段階的廃止、frozen_string_literal/deep_freezeなど、議題が幅広い。Discordから質問を取りつつ、主に日本語で進行。
キーポイント
-
新規コミッター
- モリスさん(Ruby Bot)、MAX BERNSTEIN(Shopify、YJITリード、Ruby歴16年)、スタンド・オー(Shopify、Ruby DX)、Luke(VMでのコンカレンシー)
-
String#popcount とビット操作の提案
- アーランさん提案の
String#popcount。12年前にも同様提案があったがリジェクト - Integerでなく Stringに実装するほうが適切という方向性。Stringをビット配列として扱い、
getbit/setbitなどを足す - バイトオフセット vs ビットオフセット、MSB/LSBどちら左にするかが詳細課題
- アーランさん提案の
-
ガバナンスと後継者計画
- Linux / Python のgovernanceを参考に議論
- Python: 5人程度の委員会を選挙で選出
- Matz: 委員会制には懐疑的。人数が多いと「関心のない投票者による運ゲー」になる懸念。1人 / 3人 / 5人程度の小規模が望ましい
- 「AIに全発言を学習させて『AI様の言う通り』」「メカマッツ(機械化された松本さん)」というジョーク
- 現時点で具体的な後継者は名乗り出ていない
- Linux TAB は大口スポンサー向けの政治的役割が主、技術判断には直接関与していない、という指摘
-
AIによるRuby開発
- 去年比で AI活用が大幅増
- 黒田さん: 8割のタスクでAI(デバッグ・コード生成)。方針が決まっていれば効果的、不明確なら人間が骨組みを作る
- 挙手で 半数以上のコミッターがAIで書いている
- Matz: Emacsをやめて全編集をClaude Codeに移行、一行も書いていない
- CコードよりRubyコードのほうがAIで生成・理解しやすい
- 型システムなど複雑な領域でも、AI経由で「初めて触る人」からの貢献が増えている
- TDDが苦手な人は「想定コードを書いてからAIに実装させる」やり方が有効
-
AIとRubyの将来
- 遠藤さん: Matzが長年主張してきた 「型注釈なしで高度な解析が可能」 という未来が、AIにより現実味を帯びてきた
- 各言語でVCSの簡易実装をAIにやらせる比較実験。RubyはAIによる生成と相性が良い可能性
- 一方でAIのリソース消費の持続可能性に懸念
-
setjmp/longjmp の段階的廃止
- 青井さん提案。Ruby VMは
setjmpで状態を保存し、例外時にlongjmpでタイムトラベル的に戻る仕組みになっている - JITコンパイラのレジスタ割り付けで
longjmpが大きな障害 - Pythonは
longjmpを使わずエラーフラグで順次処理 - Rubyユーザー影響なし、VM実装と C 拡張に影響(特に
rb_raise等) - 4.1 / 4.2で段階的に進める計画。メモリリークのリスク低減も期待
- 青井さん提案。Ruby VMは
-
frozen_string_literal と deep_freeze
-
frozen_string_literalをデフォルトにする準備状況 -
frozen_array_literal/frozen_hash_literalの提案も - deep_freeze: オブジェクトと参照先を再帰的にfreeze。16年前にも提案あり
- クラスをfreezeするかが大きな論点。現提案は複雑なルール
- 実用上は配列・ハッシュ・数値・シンボルが中心
-
自分の学び
- Matzのガバナンス観 ―「人数が多いと関心薄い投票で運ゲー化する」― は、OSSに限らずチーム意思決定にも刺さる原則。意思決定者の人数 × 関心強度を意識する。
2. The Less-Told Story of Socket Timeouts
概要
Ruby 2.3 → 3.4にかけてのSocketライブラリのタイムアウト機能実装史。名前解決から接続完了までの各段階で、どうタイムアウトを入れていったかを時系列で追う、技術的歴史物語。getaddrinfo_a の罠、Happy Eyeballs v2、open_timeout 導入までの変遷が見どころ。
キーポイント
-
Ruby 2.3: connect_timeout 導入
- Socket TCP / TCPSocket は複数IPがある場合、ひとつずつ試す
- 各接続にタイムアウトを掛けるが、アドレス数 × タイムアウトで全体が伸びうる
-
Ruby 2.5: Resolv にタイムアウト追加
- Net::HTTP が Timeout ライブラリ依存だった背景。名前解決〜接続完了の全体時間を管理したい
- 課題:
getaddrinfoはブロッキングで割り込み不可、Ctrl+Cも効かない - 解決:
getaddrinfo_aをワーカースレッドで実行、メインは完了待ち -
resolv_timeoutキーワードがSocket TCPに追加
-
Ruby 3.0: Happy Eyeballs と
getaddrinfo_aの罠- 並行処理機構の改善で
getaddrinfo_aの利用範囲が拡大 - TCPSocket / Socket TCPに
resolv_timeout/connect_timeout -
重大バグ: Fiber / Thread内で
Socket.getaddrinfoがさらにSocket.getaddrinfoを呼ぶと反応しなくなる- 原因:
getaddrinfo_aのワーカースレッドが共有プールで、待機中に別のgetaddrinfoを呼ぶと整合性が崩れる
- 原因:
- 並行処理機構の改善で
-
Ruby 3.1-3.2: デッドロック対応
- 1年以上の議論。Ruby 3.2 で
getaddrinfo_aを使わない実装に戻す - 新しい中断方式: Fiberと組み合わせる。新Fiberで
getaddrinfoを実行、再開時に即終了 - これにより
Socket.getaddrinfo/Resolv.getaddrinfoが中断可能になった
- 1年以上の議論。Ruby 3.2 で
-
Happy Eyeballs Version 2
- IPv6 と IPv4 をほぼ同時に名前解決、先に完了したほうで接続開始
- タイマー:
resolv_timeout(名前解決全体)/connect_timeout(各接続試行) - 失敗したら次のアドレスへ
-
タイムアウトの重複問題
-
connect_timeout 1分 + resolv_timeout 1分で、最大2分かかる可能性 - 両者では「全体何分以内に終わる」を厳密に保証できない
-
-
Ruby 3.4:
open_timeout導入- 名前解決〜接続の全体時間を管理する新キーワード
-
open_timeout + connect_timeout併用は ArgumentError -
open_timeout + resolv_timeoutは 早いほうが勝つ - 重要な発見: Ruby 3.3 はAPIだけで実装が伴っていなかった。3.4でようやく完全機能
- 実装: TCPSocket / Socket.tcp が共通で呼ぶ
Addrinfo.foreachにopen_timeoutを流し、接続側は残り時間を計算してconnectのタイムアウトに渡す
-
その他
-
open_timeout導入後、Net::HTTPのTimeoutライブラリ廃止提案あり - Happy Eyeballs実装の改善継続中
-
3. Ruby Releases Ruby(hsbt)
概要
Rubyを使ってRubyをリリースする、というメタな話。リリースマネージャーの作業時間を1時間未満に圧縮し、隔週リリースを実現するまでに至ったCI/CD・自動化・インフラ管理の現状報告。RubyGems/Bundler 4.x、OIDC Trusted Publisher + Sigstore、バックポート自動化、AIの位置づけまで。
キーポイント
-
リリースプロセスの進化
- リリース頻度は3〜4年前比で 2〜3倍。今は 隔週リリース
- 2022: 年9回 → 2024-2025: 14〜15回
- セキュリティリリースは2024年秋に完全自動化、翌日対応可能に
- リリースマネージャーの実作業は1時間未満で完了
-
CI/CD基盤
- GitHub Actions + Ruby CI の2層構造
- GitHub Actionsは1コミットあたり 約120ジョブ
- In-source / out-of-source ビルド両方で網羅性確保
- プラットフォーム × ビルドパターン × configure オプションの組み合わせ管理
- 網羅性の高いテスト戦略の設計はAIにはまだできず人間が判断
-
chkbuild
- Ruby CI は Rails アプリでログ集計
- 実行は chkbuild(田中明さん作)
- プラットフォーム横断で統一ログ形式
- 前回テスト結果との diff表示 で「どのコミットで失敗し始めたか」を即時検知
- 5年前・4年前の記録も保存
- CIが失敗したら即修正、1週間で直らなければrevert の文化
-
インフラ構成管理
- mitamae(mRuby製のChef的ソフトウェア)。シングルバイナリでクロスコンパイル可
- S390 / ARM64 FreeBSD などニッチ環境でも統一構築
- 「徹底的にRubyで書く」ことでレバレッジを効かせる
-
リリース自動化
- 人間の判断は 「タグを打つタイミング」「公開アナウンスのタイミング」の2回だけ
- GitHub の
repository_dispatchでリポジトリ間ワークフロー連携 - タグpush → リリースパッケージ生成 → 通知 → 公開トリガーで Docker / Homebrew / ruby-lang.org 雛形を自動生成
-
ツール開発のワークフロー
- 発表者が素朴なRubyを書く → 国分さんが汎用化・エラー処理 → 中田さんがRubyらしく書き直す、という流れ
- GitHubリリースノートの自動生成(コミット範囲 → Redmine/PR参照を抽出してリンク化)
-
RubyGems 4.x
- 2024-12 に 4.0 リリース、以降も積極バックポート
- 一部企業で 1分20秒〜90秒の高速化
- Ruby 4.1: YAMLライブラリ依存を削除予定
- Claude にゼロからYAMLパーサーを書かせて実装
- RubyGems top 5000 全インストール検証済み
- Cの依存ライブラリが減ることで依存チェーンが改善
-
Bundler プラグイン改善
- プラグインのドキュメント不足でAI(Copilot/Claude)でも書けない
- BundlerはThor使用 → Thorのドキュメント+ソースを読む必要
- 新機能はBundler本体ではなくプラグインで実現する方向性
-
OIDC Trusted Publisher と Sigstore
- OIDC Trusted Publisher: GitHub Actions から MFA 不要で gem push 可
- release-gem ワークフロー: git tag push で自動リリース、クリーンな環境
- Sigstore: バイナリがどのGitHub Actionsで生成されたかを証明
- RubyGems 4.1 から本体取り込み(以前はMonkey Patchで実現)
- プリコンパイルバイナリのトレーサビリティ確保が次の目標
-
バックポート自動化
- 特定ラベル付きPRを全自動でバックポート
- cherry-pickリスト → CI/テスト → 通過したらリリース
- 課題: コミットAだけ取ってもB/Cが要るケース。CI失敗時に「追加バックポート / 諦め / パッチ」を人間が判断
-
今後
- RubyGems/Bundler自身もGitHub Actions上でリリース → Sigstore署名
- AIでできることは増えても、「何をリリースとするか」「複数コードのコンテキスト」「CI設計」は人間が決める
- 少人数 × Rubyで生産性を最大化
Discussion