こんにちは!
食べログカンパニー開発本部ウェブ開発 2 部の濱口 (@machida4) です。
4 月 16 日 ~ 18 日に松山で開催された RubyKaigi 2025 に参加しました。
この記事では、RubyKaigi 2025 の注目セッションをご紹介します。
どのセッションも大変興味深いものばかりでしたが、全部盛りにするとスクロールバーが見えなくなってしまうので、特に印象に残ったセッションをいくつかピックアップします。
目次
- 目次
- Ruby Taught Me About Encoding Under the Hood
- Empowering Developers with HTML-Aware ERB Tooling
- State of Namespace
- Toward Ractor local GC
- Analyzing Ruby Code in IRB
- Ruby のこれから
- まとめ
Ruby Taught Me About Encoding Under the Hood
最初にご紹介するのは、1 日目の基調講演である、@ima1zumi さんの Ruby Taught Me About Encoding Under the Hood です。
Unicode の登場背景や、ご自身が「文字コード沼」にはまった経緯、そして Ruby を最新の Unicode バージョンへ対応させるまでの奮闘が語られました。
書記素クラスタについて
今回の発表では、書記素クラスタの扱いがテーマのひとつとなっていました。
書記素クラスタ (Grapheme Cluster) は、見た目上 1 文字としてみなされる Unicode の Code Point の集合です。
例えば、「👨👩👧👦」という絵文字は、複数の絵文字 (👨
, 👩
, 👧
, 👦
) を指す Code Point をゼロ幅接合子 (U+200D
) で結合したものです。
これを書記素クラスタ単位で見ると、以下のように 1 文字扱いされます。
どのように書記素クラスタに分割するかは、Unicode 標準のUnicode Standard Annex #29 で定められています。
感想と余談
具体例とユーモアたっぷりで、とてもわかりやすく楽しいセッションでした。
また、@ima1zumi さんがひょんなことから OSS 活動に関わり出し、Ruby のコミッタになるまでの経緯はかなりぐっとくるものがありました。 好奇心を大事にして、チャンスがあったら積極的に挑戦していく姿勢を持ちたいと思いました。
ちなみに、余談ですが、Ruby の文字コード周りは奥が深く、他にも興味深いトピックがたくさんあります。
例えば、多くのプログラミング言語では、内部的な文字列の扱い方を Unicode のような特定の文字コード体系に統一する「UCS Normalization」という方式を採用しています。
しかし、Ruby はそれとは異なる「CSI (Code Set Independent)」という、少し珍しいアプローチを取っています。
UCS Normalization は、システムの内部的な文字列の持ち方を、一つの文字集合に統一して扱う方式です。 Ruby 以外のほとんどの主要な言語ではこの方式を採用しています。例えば JavaScript では、文字集合を Unicode に統一して扱い、文字列は UTF-16 の Code Unit の列として扱います。
UCS Normalization は非常にシンプルでわかりやすいですが、文字コードの変換の際に情報が失われることがある、エンコーディングの変換のオーバーヘッドが生じるというデメリットがあります。また、Unicode 外の文字に関しては標準の文字列クラスでは扱えないことがほとんどです。
一方、Ruby が採用する CSI 方式は、特定の文字コードに依存せず、あらゆる文字コードを対等に扱います。 文字列は 単なる Unicode の集合ではなく、バイナリとエンコーディングのセットとして保持されます(そのため、その気になれば String クラスで自作の文字コードを扱うことも可能です)。
多様な文字コードの扱いに歴史的に苦労してきた日本で生まれた言語ならではの、非常にユニークな特徴だと思います。
Empowering Developers with HTML-Aware ERB Tooling
続いては、Hotwire のコミッタでもある @marcoroth さんの Empowering Developers with HTML-Aware ERB Tooling です。
このセッションでは、@marchroth さんが開発している、HTML をより深く理解できる新しい ERB パーサー herb が紹介されました。
herb について
RubyMine や LSP (Language Server Protocol) といったツールの登場は、Ruby の開発環境を大きく前進させました。
コード補完や定義ジャンプといった機能は、開発者体験を飛躍的に向上させましたが、HTML が埋め込まれた ERB テンプレートにおいては、その恩恵を十分に享受できていませんでした。 これは、従来のパーサーが Ruby のコードと HTML 構造の両方を正確に解析できなかったためです。
herb は、Ruby 3.3 で導入された新しいパーサー Prism を基盤としています。 Prism により、ERB テンプレート内の Ruby コードと HTML 構造を正確に解析し、DOM ツリーと Ruby コードの AST が相互に入れ子になるような、よりリッチな木構造を生成することが可能になりました。
Playground で herb を触ってみる
公式の Playground でパーサーを実際に試すことができます。
以下のように、HTML タグの中に Ruby コードが埋め込まれ、さらにその中に HTML タグが埋め込まれたテンプレートであっても、問題なく解析できていることがわかります(Share URL)。
感想
Ruby on Rails は (流行に抗って?) ずっと HTML 中心のアプローチを取り続けていますが、その HTML を生成する ERB テンプレートの扱いやすさは Rails の開発体験に直結します。
今後 herb のエコシステムがさらに充実すれば、ERB テンプレートを扱う開発者の生産性を大幅に向上する可能性を秘めていると感じました。
よかったら haml のパーサーも...🥺。
State of Namespace
続きまして、@tagomoris さんの State of Namespace です。
Ruby の新しい言語機能のひとつとして開発が進められている Namespace の紹介と現在の状況、そして今後の展望についての発表でした。
Namespace について
Namespace は、アプリケーションコードやそれが依存しているライブラリのコードを、それぞれの名前空間で管理することで、名前や定義、バージョンの衝突を防ぐことができる機能です。
Namespace で区切られたコードは異なるトップレベル名前空間を仮想的に持つので、例えば同じアプリケーション (プロセス) の中で異なるバージョンのライブラリを用いることができます。
感想
Namespace の最新の状況だけでなく、デバッグの過程の紹介を通して、CRuby (MRI) の内側でどのようなことが行われているかのイメージを知ることができるセッションでした。
後方互換性のないライブラリのバージョンアップなどの際に、Namespace を区切って少しづつ移行を進めたり、グローバルな設定の影響範囲を限定したりと、食べログのような大規模開発プロジェクトにおいて特に実用性が高い機能です。モノリス開発者にとっての福音になるんでしょうか。
Toward Ractor local GC
次にご紹介するのは、@ko1 さんの Toward Ractor local GC です。
Koichi Sasada: Toward Ractor local GC,
— Koichi Sasada (@koichisasada) April 18, 2025
RubyKaigi 2025, Ehime, Japan (2025.04).https://t.co/DiGi7TsYDT (842KB)https://t.co/lDjUkixFqU#rubykaigi #ractor
Thank you for listening!!
Ractor の仕組みに、各 Ractor に固有な (Ractor-local な) ガベージコレクション機構を導入する提案についての発表です。
Ractor について
Ractor は、Ruby 3.0 で導入された、Ruby で安全に並列実行を実装するための仕組みです。
CRuby (MRI) には GVL (Global VM Lock) という仕組みが存在します。
GVL は、Ruby インタプリタ全体で一つの大きなロックを持つ仕組みです。いかなる時点においても、Ruby のコードを実際に CPU で実行できるスレッドは 1 つだけに制限されます(ただし、スレッドがファイル I/O やネットワーク通信などの I/O 待ち状態にある間は GVL を解放されるため、スレッドを増やせば、I/O バウンドな処理は十分スケールします)。
gvl-tracing という gem を使うと、以下の画像のように各スレッドが GVL を奪い合う様子を確認できます。水色のバーが GVL を獲得しているスレッドを表しています。
GVL を用いることで、C 拡張などを含む環境でスレッド安全を容易に担保できる一方、CPU バウンドな処理ではスレッドを増やしても性能が向上しないという課題がありました。
Ractor では、各 Ractor がそれぞれが独立した GVL を持つため、複数の Ractor が異なる CPU コア上で同時に Ruby コードを実行できます。 GVL による制約を受けることなく、CPU バウンドな処理での並列性を引き出すことが可能です。
Ractor local GC
現状の実装では、全ての Ractor がグローバルヒープを共有しているため、GC の実行時に全ての Ractor を停止する必要があります(Stop-the-world)。このグローバルな GC が、システム全体のパフォーマンス低下を招き、Ractor による性能向上を妨げていました。
理想的には、各 Ractor が持つメモリ領域ごとに GC を独立して実行できれば解決できます(実際、Elixir などでは同様のアプローチが取られているようです)。しかしながら、Ractor 間で共有可能なオブジェクト(Sharable objects)が存在するため、参照関係の完全な把握が難しく、単純なローカル GC の実現は困難です。
そこでこの発表では、完全な並列 GC は諦め、他の Ractor と共有されないオブジェクトについては各 Ractor で独立して GC を行い、共有可能なオブジェクトについては従来通りグローバルな GC を行う、というハイブリッドなアプローチを提案しています。
このアプローチにより、いくつかのベンチマークにおいて、Ractor 数を増やしても性能が低下せず、スケールする結果が得られたとのことです。
感想
Ractor という窓を通して、GVL や GC といった Ruby の心臓部について、その一端を知ることができました。
Ractor はまだまだ発展途上で、乗り越えなければならない壁がたくさんある印象ですが、個人的には非常に楽しみな技術なので、これからも注目していきたいです。
純 Ractor 製の HTTP サーバーが登場して、颯爽と unicorn や puma を追い越す日が来るのでしょうか!?
Analyzing Ruby Code in IRB
最後に、@tompng さんの Analyzing Ruby Code in IRB をご紹介します。
これからの発表「Analyzing Ruby Code in IRB」の資料ですhttps://t.co/6HBisYOemv#rubykaigi
— ぺん! (@tompng) April 18, 2025
IRB のさまざまなコーディング支援機能の裏でどのような解析が行われているか、パーサーを Prism に切り替えて何が可能になったかについての発表でした。
Ripper::Lexer to Prism
IRB の内部で用いられるパーサー(レキサー)としては長らく Ripper::Lexer が中心でした。
構文エラーが発生してもそこで終了せず、可能な限り解析を継続できるパーサーが Ripper 以外に存在しなかったため、不完全なコードを扱う必要がある IRB では、他に選択肢がなかったようです。
ただし、Prism が登場し、Ruby3.3 の default gem になった現在では、Prism への置き換えが進められているようです。
Prism によって、トークンだけでなく 詳細な構文木 レベルの解析が可能になったことで、IRB のコーディング支援機能が大幅に強化されました。例えば、以下のシンタックスハイライトは、トークンの情報と構文木の情報を組み合わせることで可能になっているそうです。
感想
日頃何気なく使っている IRB の裏側では、こんなにも色々な工夫が詰まっているんだな〜と感動しました。
また、奇妙な Ruby コードを書く達人 の @tompng さんらしく、Ruby の文法上の様々なエッジケースを考慮した上で、スマートな解法で対処しているのが非常にカッコよかったです。
ぼくも Quine を書きまくっていたら、最強のプログラマーになれるんでしょうか? とりあえずあなたの知らない超絶技巧プログラミングの世界をポチるところから始めてみました。
Ruby のこれから
今回の RubyKaigi では、Prism を基盤としたツールに関する発表が多かったのが印象的でした。
IRB
の進化、herb
のようなツールの誕生は、開発効率を飛躍的に向上させる可能性を秘めており、日々の開発を快適にしてくれそうです。
また、Namespace
や Ractor local GC
、新世代の JIT コンパイラである ZJIT
といった、Ruby が抱えていた課題への挑戦や、将来のパフォーマンス向上を見据えた意欲的な取り組みも進んでいます。
Ruby のこれからの進化がますます楽しみですね。
まとめ
ご覧いただきありがとうございました。
オフラインで RubyKaigi に初参加しましたが、想像以上の熱気でした。
Ruby の開発者たち、日頃お世話になっている OSS の開発者たちが一同に会して、その熱意をぶつけてもらえるというのは、唯一無二の貴重な経験です。正直最先端すぎてついていけない発表ばかりでしたが、最高にカッコいいハッカーたちの姿から、モチベーションを得ることしきりでした。
食べログでは Ruby on Rails を用いて大規模なサービス開発を行っており、Ruby コミュニティの動向や新しい技術にも注目しています。
今年からは全社的に「OTAKU SPIRIT」というバリューを掲げており、技術にこだわりを持ってサービス開発に取り組む文化があります。
Rails を使った大規模なサービス開発や、食べログの開発チームに興味を持っていただけましたら、ぜひ以下の採用情報をご覧ください。