2025年4月16日から18日の3日間、愛媛県松山市にて、RubyKaigi 2025が開催されました。
タイミーでは、昨年に続き、世界中で開催される技術系カンファレンスに無制限で参加できる「Kaigi Pass」という制度を活用し、新卒内定者やインターン生を含む総勢16名が現地でカンファレンスに参加しました。
本レポートでは、Day1の様子を、参加したエンジニアが注目したセッションごとに、ポイントや得た知見をまとめてご紹介します。
今後も、Day2 vol.1、Day2 vol.2、Day3と続けてレポートを公開予定です。
各セッションごとに内容を整理し、参加者自身の視点から学びや気づきをまとめています。読者の皆様にとって、今後の学びの参考になれば幸いです。
Make Parsers Compatible Using Automata Learning
概要
Ruby のパーサーである parse.y と Prism には非互換性が存在するが、それを検知するためには本来膨大なテストが必要になる。筆者はオートマトン理論を応用することでそれぞれのパーサーの不一致性を定量的に検出できるのではないかという仮説を立て、限定的な条件を当てはめて試行してみた結果、見事にバグを検出して修正することができた。
感想
若いうちから才覚を発揮して個人的に敬愛している makenowjust さんの発表です。内容は概要の通り。
研究とかだとよくある話ですが、現実世界の複雑性に対して理論をそのまま適応できずにより限定されたスコープにのみ理論を適用する、というアプローチがしばしば見受けられます。
今回もそのケースで、Ruby の文法全体は文脈自由言語なので今回の定式をそのまま適用することはできないため、Visibly Push-down Automaton の適用範囲に限定しています。
今回の発表で私が意義深いと思ったのは、その限定されたスコープにおいてもバグの検出に成功したこと、そして、そのバグの修正をコミットすることで言語コミュニティに成果をきちんと還元していることです。
10年近く前に私が大学で卒論を書いたときには研究室のアウトプットがコミュニティから断絶されていて論文を書いたあとも放ったらかしになっていたことを嘆きましたが、こうやってきちんと行動している人物がいることを考えると日常の忙しさに逃げていた私は視座が低かったなと恥じる思いです。
(@Hiromi Kai)
Ruby's Line Breaks
概要
Ruby における改行の扱いと例外、そしてその背景にある技術的な複雑さを紹介してより理解しやすい解決策を提案しています。
感想
Ruby における改行の背後に潜む lexer state という「混沌への扉」といかに向き合って克服していくかという、周辺知識のあまりない自分には中々難しい話ではありましたが、発表者の @spikeolaf さんが、分かりやすく、かつ引き込まれる語り口で解説してくれたので興味を持つことができました。他の Ruby コミッターの方も「理解不能」「怖い」「完全に理解できる人はいない」と語るほど複雑な lexer state をモデル化して最終的には完全に排除したいという壮大な目標を掲げており、いつか「混沌への扉」が閉じることを楽しみにしたいと思います。
(@ creamstew)
Introducing Type Guard to Steep
概要
RBS のエコシステムに積極的に contribute されている @tk0miya さんによる、RBS の Type Guard による Type Narrowing(型の絞り込み)をより便利にしたよ、という発表でした。
Ruby の型チェッカーSteepは型の絞り込みをサポートしていますが、is_a? や nil? などの基本的なメソッド以外(例: Active Support の present? やユーザー定義の判定メソッド)では、開発者の意図通りに型が絞り込まれず、冗長なコードや誤った型エラーが発生することがありましたが、この問題がある程度解消されます。
既に本体に取り込み済みの Union Type に対する Type Guard と提案中の User-Defined な Type Guard の紹介がメインになっています。
感想
タイミーでも実際に RBS/Steep を使っていて、意図した挙動とは異なる挙動を Steep がとることは稀によくあります。そのときは社内にいる soutaro さんに共有し、手元の実装を修正するか本体に変更を入れてもらうかを相談することがちょくちょくあるのですが komiya さんは自ら提案をしパッチを送る活動をされていて流石だなと感じました。
User-Defined な Type Guard も大変魅力的でこれが導入されると、Ruby での静的型付けの表現力の幅がグッと広がるのではないかと感じています。タイミーの中でも状態に応じてメソッドの返す値が異なるものは存在します。それらに対して User-Defined Typed Guard がどう活用できるのかを改めて考えてみたいと思いました。
(@euglena1215)
発表の主旨とは少しずれますが、この機能を使ってメソッドの呼び出し順序を表現することもできそうだなぁと思って興味深く聞かせていただきました。
型の絞り込みが期待通りできず、コードが冗長になる(e.g. something || raise
)という経験は多いですが、多過ぎて慣れてしまったので、この発表を聞いてそういえばそうかもなぁという気持ちになりました。この辺りを表現するために複雑な型を書くことを要求されると、なかなか普及はしないかもしれないですが、Union Type に対するものについては、開発者が特に複雑な何かをする必要がなさそうなので純粋に嬉しいなぁと思いました。
(@rhiroe)
Deoptimization: How YJIT Speeds Up Ruby by Slowing Down
概要
YJIT を開発されている @k0kubun さんによる発表。
YJIT が Ruby のコードを最適化するために、あえて一部の処理を非最適化しているという内容でした。
YJIT の最適化されたコードが、場合によっては逆に効率が悪くなってしまうため、必要に応じて元のインタープリタ実行に戻すということを行っているとのことです。
またCで実装されたメソッドと、Ruby で実装されたメソッドの比較も行われ、C と Ruby のコードの境界を複数またぐ場合にはボトルネックが発生し、YJIT の特性を考慮した実装戦略が必要であることに触れられていました。
感想
YJIT は有効にするだけで使い方を意識する必要なく Ruby アプリケーションが高速化される魔法のような技術だと考えていましたが、その裏側では非常に複雑な技術基盤のもと成り立っているということを感じました。
タイトルにあるとおり高速化を行うためにあえて非最適化を行うという、直感と反する実装が行われていることが興味深かったです。
低レイヤーの知識に触れる機会がこれまでなかったのですが、コンパイラの実装に興味を持つきっかけとなりました。
(@Keisuke Kuwahara)
Ruby Taught Me About Under the Hood
概要
このセッションでは、文字エンコードの歴史から発表者である @ima1zumi さんの運命的な(?)出会いをした EBCDIC、そこから Ruby と出会い Ruby の文字エンコードに貢献していくまでの道のりと対応の苦労が紹介されていました。
感想
私はプログラミングを始めてから、そこまで文字コードに深く思い入れを持たずこれまでのエンジニアキャリアを過ごしてきました。
そのため、コメントでエンコーディングがおかしくなることを避けるために半角カタカナしか使わないことがあったというのは衝撃でしたし、Code Point と UTF-8 byte sequence が別物というのもあまり考えたことがありませんでした。
複数の Code Point で構成される絵文字 🧑🧑🧒🧒 が存在し、Unicode 15.1.0 からは Indic_Conjunct_Break for Devanagari をサポートするために新たなハンドリングのルールを実装する必要があったことなど、文字コードの奥深い世界を垣間見れてとても面白かったです。まさか Unicode アップグレード対応をするためには世界の言語体系に精通している必要があるとは思ってもいませんでした…。
(@euglena1215)
Opening Keynote が文字コードという、なかなか通好みなテーマだったのに自分は驚きましたが、蓋を開けてみれば @ima1zumi さんの文字コード愛にあふれる技術的な解説の面白さと、その愛を突き詰めた結果として Ruby のコミッターになったというストーリーのエモさがクロスオーバーする、最高のセッションでした。
セッションに登場した EBCDIC については、自分はメインフレームの経験がないため知らなかったのですが、銀行システムで半角カナが多く使われる理由に関係しているのかもしれない、などと想像がふくらみ、非常に興味を持ちました。(とはいえ業務で扱いたいとはあまり思いません)
セッションを通して、文字コードは「文化」と「技術」の交差点であることを改めて実感しました。人間の曖昧で多様な文字を、コンピュータの厳密で機械的なルールに落とし込むという課題は、非常にエキサイティングだと思います。 とりあえず『プログラマのための文字コード技術入門』をもう一度読み直そうと思います。
(@sugaishun)
Automatically generating types by running tests
概要
テストを実行するだけで、メソッドの引数や戻り値の型情報を収集し、RBS 形式のコメントをRuby コードに自動挿入するツール rbs-trace gem を開発したという内容です。
技術的には、Ruby の TracePoint API を利用し、メソッド呼び出し時(:call)とリターン時(:return)の情報をフックして引数や戻り値のクラスを取得し、それを型情報にしてコメントを挿入します。
Model::ActiveRecord_Relation.name で ActiveRecord::Relation が取得されてしまうといったような例を挙げ、klass.name では正確なクラス名が取得できず、UnboundMethod を利用して実際のクラス名を取得するといった工夫も披露してくださいました。
また void 判定にも苦労されたそうで、Prism ライブラリでコードをパースし、AST(抽象構文木)を解析。メソッド呼び出しがdef直下かつメソッド定義の最後の処理でない場合に、戻り値が利用されていないと判断し void 型とするとしたそうです。
感想
型の導入については、特に既存のRailsアプリケーションへの導入のハードルが高く、不完全なものであっても一通り型情報を用意するというだけでも大変なコストがかかります。
この rbs-trace を使えば、テストを実行するだけである程度の型コメントが手に入るので、これから型を導入しようと考えているものについてはとても助かるライブラリだろうなと思いました。
rbs-inline と併用することを前提とされている点もよく、rbs-inline は型コメントがなければuntyped で RBS が生成されるので、これで(不完全な)型情報が(動的に生成されたものや移譲されたメソッドを除いて)一通り揃うことになります。型導入の最初の一歩としては十分すぎるくらい型情報が揃うので、型導入やってみたいけどハードルが高いと感じていそうな組織があれば推していこうと思いました。
(@rhiroe)
おわりに
RubyKaigi 2025のDay1も、実践と研究の境界線を行き来するような深い技術セッションが続き、Ruby という言語が進化を続けていることを改めて実感する一日でした。
低レイヤの最適化、型システムの発展、文字コードという文化的テーマまで、まさに“Ruby らしさ”が詰まったセッションばかりで、各登壇者の情熱や貢献から多くの刺激を受けました。
Day2、Day3にも魅力的なセッションが数多く控えています。今後公開予定のレポートも、引き続きどうぞご期待ください!