2025年4月16日から18日の3日間、愛媛県松山市にて、RubyKaigi 2025が開催されました。
タイミーでは、昨年に続き、世界中で開催される技術系カンファレンスに無制限で参加できる「Kaigi Pass」という制度を活用し、新卒内定者やインターン生を含む総勢16名が現地でカンファレンスに参加しました。
この記事では、現地参加した各エンジニアの印象に残ったセッションとその感想をまとめてお届けします。
今回はその第3回で、前回に引き続きDay2の内容をまとめています。Day3のレポートも近日中に公開予定です。
読者の皆様にとって、今後の学びの参考になれば幸いです。
RuboCop: Modularity and AST Insights
概要
セッションでは、主に以下の 3 つの主要なテーマについて掘り下げられました :
- Ruby LSP Add-on: Ruby Language Server Protocol (LSP) のアドオン機能に関する議論がなされました。Shopify製のruby-lspをRails開発コンテナで使用している現状を踏まえ 、RuboCop、StandardRuby、Ruby LSPがそれぞれ独自のLSP実装を持っている非効率性を指摘し 、RuboCopのLSPランタイムの統一が提案されました。Ruby-LSPのAdd-on機能を利用し、RuboCopの組み込みLSPランタイムを再利用する実験的な試みが紹介されました。これにより、複数の開発ツールと連携するRuby LSPの利点を活かしつつ、各ツールでのコード解析の重複を避けることが期待されます。
- Plugin System: RuboCopのプラグインシステムの刷新について詳細な説明がありました。従来、非公式なモンキーパッチである "Inject" ハックが拡張機能の事実上の標準となっていましたが、設定の衝突やロード順序による不整合などの問題点がありました。この課題を解決するため、公式の拡張APIとなりうるプラグインシステムがRuboCop 1.28で導入されました。この新しいプラグインシステムは、Linterプラグインの仕様に基づいており、安定した抽象インターフェースを提供し、RuboCop内部で設定を管理します。プラグインの利用者と開発者向けに、具体的な移行方法や実装方法が解説されました。
- AST Insights: Abstract Syntax Tree (AST) に関する洞察として、特にParser gemとPrismという2つのRubyパーサーに焦点が当てられました。メンテナンスの課題を抱えるParser gem に対し、Shopifyが開発するPrismがより将来性のあるパーサーとして紹介されました。RuboCop 1.27からPrismをオプションのバックエンドとして利用可能であり、RuboCop 1.28以降では Ruby 3.4以降のデフォルトパーサーとしてPrismの変換レイヤーを使用することで、構文の互換性を確保し、メンテナンスコストを削減しています。PrismのASTを直接利用することの利点と課題についても議論されました 。
全体として、このセッションは、RuboCopの拡張性とRubyエコシステムとの連携を強化するための重要なアップデートと、Rubyコード解析の基盤となるASTパーサーの進化について、最新の情報と将来の展望を提供するものでした。
感想
今回のセッションは、RuboCopが単なるコードフォーマッター、リンターから、より広範な Ruby開発エコシステムの中核となるツールへと進化しようとしている意欲を感じさせる内容でした。
特に印象的だったのは、公式のプラグインシステムの導入です。これまで、サードパーティの拡張機能は "Inject" ハックという、やや不安定で保守性の低い方法に依存していたため、今回の刷新はRuboCopのエコシステム全体の健全性を高める上で非常に大きな進歩と言えるでしょう。プラグイン開発者にとっては、より安定したAPIを利用できることはもちろん、設定管理がRuboCop側で統合されることで、より本質的なCopの開発に集中できるようになるのではないでしょうか。
また、Ruby LSPとの連携も注目すべき点です。異なるツールが個別にLSP機能を持つのではなく、RuboCopの持つ強力な解析能力をRuby LSP経由で他のエディタやIDEでも活用できるようになることは、開発者体験の向上に大きく貢献すると感じました。まだ実験的な段階とのことですが、今後の発展が非常に楽しみです。
そして、ASTパーサーをParser gemからPrismへと移行する動きは、Rubyの進化に追従し、より現代的な構文をサポートするための必然的な流れだと感じました。Parser gemのメンテナンスが困難になっている現状を踏まえると、Shopifyが積極的に開発しているPrismを採用することは、RuboCopの将来的な安定性と機能拡張にとって重要な決断と言えるでしょう。翻訳レイヤーを介してParser gemのAPIを維持しつつPrismを利用するというアプローチは 、既存のRuboCopのエコシステムへの影響を最小限に抑えながら、最新のRuby構文への対応を進めるための賢明な戦略だと感じました。ただし、将来的にはPrismネイティブのASTへの移行も視野に入れているような議論もあり、その際の移行コストや互換性維持が重要な課題となるでしょう。
全体として、このセッションは、RuboCopの内部構造のモジュール化を進め、より多くの開発者やツールとの連携を強化し、そしてRuby言語の進化に柔軟に対応しようとするKoichi ITO氏をはじめとするRuboCopチームの強い意気込みを感じさせるものでした。今後のRuboCopの発展がますます楽しみになる発表でした。
(@hiroshi)
概要
本登壇はRubocopに関するトピックを三本立てで提供する。最初にRubocopプラグインシステムの導入により、拡張性を持たせるとともに、非公式なモンキーパッチが横行することで安全でない書き方を一掃することを目指している。
次に、Ruby LSPアドオンは、RubocopのデフォルトのLSPにアドオンとしてRuby LSPを組み込めるようにした。これは、Ruby本体、Rubocop、Ruby LSPが今までバラバラにLSP実装を持っていたものを統合することを狙いとしている。ステータスとしてはまだExperimentalでデバッグの最中である。
最後に、Rubocopの内部ASTとしてPrismを採用したことと、それまでの検討についての発表を行っている。Prismに関しては今年のRubyKaigiでも様々な活用が発表されたが、並行してparser gemのメンテナンスが縮小しているという背景もあり、Rubocop 1.75からはRuby 3.4以降のバージョンではデフォルトのパーサーがPrismとなる。また、Prismとparser gemでASTの互換性を保つためにPrism::Translation::Parserというクラスを用いている。
感想
思い出話をしますが、私は2社前、7年ほど前は超Rubocopアンチでした。
時間をかけてじっくり適応して今となっては当たり前のものとして使用できていますが、ルール同士が競合し合ってダブルバインドしてくることにブチ切れたのも懐かしい話です。
さて、登壇者のkoicさんには「なんか毎年RubyKaigiで登壇してんな」という印象を持っていますが、実際その通りで私が初めて参加した2018年仙台から登壇が途切れておらず、私がひよっこのRailsエンジニアとして「Rubocop使いづれー!」と叫んでいた頃からこのように持続的なアウトプットを続けていることが、Rubocopをデファクトスタンダードの開発ツールとしての立場を揺るぎないものにしているんだなという敬意を覚えます。
そして今回の発表内容である、プラグインシステムやデフォルトパーサの変更もまさしくプロダクトの鮮度を保つための持続的な開発であると言えます。
gemのちょっと込み入った利用方法になってくると途端に情報が少なくなって、書いている人も意味がよくわかっていないような秘伝のタレ化したスニペットが出回る、ということは利用側としてあるあるだなという実感がありますが、そのような状況を提供側として問題視してモンキーパッチが必要ないように仕組みで解消したのは素晴らしいことだと思いました。
(@Hiromi Kai)
Keeping Secrets: Lessons Learned From Securing GitHub
概要
GitHubでの重大なセキュリティ脆弱性の発見や原因調査プロセス、教訓などが語られました。特にRubyコードにおける send メソッドの危険性を深堀りする内容となっていました。登壇スタイルも珍しい2名体制となっており、GitHub社のシニアプロダクトセキュリティエンジニアの Dennis Pacewicz 氏ならびにPraetorian社のスタッフセキュリティエンジニアの Wei Lin Ngo 氏が登壇していました。
感想
ソフトウェアエンジニアであれば誰しもがお世話になっている GitHub。それが Ruby on Rails 製のサービスであることは有名な話だと思います。Rubyistである私も以前から GitHub 社の取り組みには関心はあったものの、実はこのようなカンファレンスや技術イベントでも直接内部の開発者の発表を聞いたことはありませんでした。更に2名体制での登壇スタイルは RubyKaigi では珍しかったので興味を持って視聴しました。
まず、冒頭で GitHub のコンテナ上のすべての本番環境シークレットにアクセスできる可能性があったと語られました。非常に恐ろしい話ですね…。
具体的な原因となるプログラムでは Ruby で時折見かける send メソッドの利用がありました。私もプロダクションのコードで利用したことがあり、耳が痛い話になりそうだなと身構えました。send メソッドは強力な動的メソッドディスパッチですが、GitHub では特定のControllerにてユーザー入力された値を検証なしに send メソッドに引き渡すことで最終的にすべてのプロダクションシークレットを含むハッシュが返される処理が存在していたとのことです。紐解いていくと必ずしも send メソッドの柔軟性が必要な訳ではなく便宜上の理由程度で使用されていたようです。対応後は動的なメソッドコールは消え、特定条件に基づいてメソッドを直接呼び出すより静的で安全なコードに置き換えられました。
今回の事例で登場した send のように Ruby には便利で柔軟性のあるメソッドが存在していると思います。GitHub 社においても今回の脆弱性に繋がった事例が存在するため、業務利用する場合にはメソッドの特性や利用ケースに対するリスクの理解及びそれを検知する仕組みづくりが改めて重要だと身を引き締める機会になりました。脆弱性が見つかった場合も特定個人を非難するのではなく組織全体として学びを得て改善していくブラムレスカルチャーや、発見された脆弱性を起点に類似パターンを探すバリアント分析など、今回の脆弱性発見から恒久対応までに GitHub にて取られたアプローチも学びとして得られました。
(@edy629s)
Making TCPSocket.new "Happy"!
概要
このセッションでは、Rubyの標準ライブラリであるSocketにおけるTCPSocket.new
メソッドへのHappy Eyeballs Version 2 (HEv2) の導入について解説されました。
まず、導入の背景として、IPv4とIPv6が共存する環境での従来の接続処理の問題点、すなわち逐次的なアドレス解決と接続試行による遅延の可能性が挙げられました。これに対し、より効率的な接続確立を目指すHappy Eyeballs Version 2 (HEv2) アルゴリズムの概要、特に並行したアドレス解決と接続試行、IPv6の優先、遅延タイマーなどの特徴が説明されました。
次に、Rubyで実装されたSocket.tcp
へのHEv2導入がRuby 3.4で完了したことを踏まえ、より多くのユーザーが利用するC言語実装のTCPSocket.new
への導入における技術的な課題が詳細に語られました。主な課題として、状態管理の複雑さ、割り込み可能な名前解決の必要性、スレッド数の違い、完了検出方法の違い、そしてselect(2)
システムコールの上限による問題とpoll(2)
への移行などが挙げられました。
これらの課題に対し、状態管理を排除した新しいSocket.tcp
の実装を参考に、TCPSocket.new
では新しいスレッドを作成して並行して名前解決を行い、パイプで結果を通知する仕組みや、GVLなしで待機する関数の利用、rb_thread_fd_select()
という内部APIを活用して必要最小限の修正で対応したことが説明されました。
その結果、HEv2がデフォルトで有効になったRuby 3.4 がリリースされ、ベンチマークテストでは大幅な接続時間短縮が確認されたことが示されました。また、HEv2の有効/無効を切り替える方法や、利用上の注意点なども解説されました。
最後に、この開発に貢献した多くのRubyコミッターへの感謝の言葉で締めくくられました。
感想
この発表では、ネットワークの低レイヤーに関わる重要な機能であるHappy Eyeballs Version 2のTCPSocket.new
への導入という、非常に興味深いテーマについて深く掘り下げた解説を聞くことができました。IPv4/IPv6の共存という現代のネットワーク環境における課題に対し、ユーザーが意識することなく恩恵を受けられるような改善が、標準ライブラリに地道に積み重ねられていることに感銘を受けました。
特に、C言語での実装における並行処理の実現や、システムコールの選定、そしてそれに伴う複雑な課題を一つ一つ解決していく過程が、具体的なコードやアーキテクチャの変化と共に示されており、非常にわかりやすかったです。select(2)
の制約という普段意識しないような問題に直面し、poll(2)
への移行という大きな決断と実装を行った点など、技術的な深さと熱意を感じました。
RubyKaigiという場で、このような基盤となる技術の進化について知る機会が得られたことは、今後のRubyを使った開発においても大いに役立つと感じました。HEv2がデフォルトで有効になったRuby 3.3.0を積極的に利用していきたいと思いました。
(@hiroshi)
Happy Eyeballs V2 を TCPSocket.new
に導入する過程で直面した課題と、それらの解決策を段階的に解説してくださる、非常にわかりやすい発表でした。
Happy Eyeballs V2 が、IPv4 と IPv6 の両方に対応した環境において、より高速かつ効率的な接続確立を実現するために導入された背景についても触れられており、その必要性を理解できました。 また、RFC などの標準仕様への準拠は、これまで Ruby が対応してくれるのを待っているような感覚でしたが、この発表を通してその裏側で Ruby コミッターの方々が尽力してくださっていることを改めて認識しました。 塩井さんのご発表は、過去の RubyKaigi でも拝聴しており、そのわかりやすさを楽しみにしていました。今回の発表も期待を裏切らず、大変理解しやすく、興味深い内容でした。
(@nissy325)
おわりに
今回の記事では、RubyKaigi 2025 Day2の3つのセッション、RuboCopの進化、GitHubのセキュリティ教訓、そしてTCPSocket.newへのHappy Eyeballs V2導入について、参加者の視点からの学びと感想をお届けしました。
次回はDay3のレポートを公開しますので、どうぞお楽しみに!