Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
rbs-traceを使ってWEARで型生成を試してみた After RubyKaigi 202...
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Kei Oyama
May 16, 2025
Programming
2.6k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
rbs-traceを使ってWEARで型生成を試してみた After RubyKaigi 2025〜ZOZO、ファインディ、ピクシブ〜 / tried rbs-trace on WEAR
Kei Oyama
May 16, 2025
Other Decks in Programming
See All in Programming
「なぜそう決めたのか」を残し続ける仕組み ― Notion AI カスタムエージェント × Slack連携による設計判断の自動記録 - NIKKEI Tech Talk #47
niftycorp
PRO
0
170
TypeScript+Orvalで実現する型安全かつ堅牢でスケーラブルなマルチチャネル通知基盤 / TSKaigi Night talks ~after conference~
d0riven
0
340
決定論的オーケストレーションの設計と実装 / Design and Implementation of Deterministic Orchestration
nrslib
4
1.4k
Oxcを導入して開発体験が向上した話
yug1224
4
310
JJUG CCC 2026 Spring: JSpecify で実現する Kotlin フレンドリーな Java API 設計
ternbusty
1
170
Inside Stream API
skrb
1
710
AI時代のUIはどこへ行く?その2!
yusukebe
21
7.2k
OSもどきOS
arkw
0
560
Observability in Practice:Grafana 與 Edge Device SRE 的那些事
blueswen
0
160
Spec Driven Development | AI Summit Lisbon
danielsogl
PRO
0
190
ふつうのFeature Flag実践入門
irof
7
3.9k
AIで効率化できた業務・日常
ochtum
0
130
Featured
See All Featured
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4k
How GitHub (no longer) Works
holman
316
150k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
440
Speed Design
sergeychernyshev
33
1.8k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.7k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.2k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
370
How to make the Groovebox
asonas
2
2.2k
The SEO Collaboration Effect
kristinabergwall1
1
480
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.4k
Raft: Consensus for Rubyists
vanstee
141
7.5k
Transcript
rbs-traceを使って WEARで型生成を試してみた 株式会社ZOZO ブランドソリューション開発本部 WEARバックエンド部 バックエンドブロック 小山 慧 Copyright ©
ZOZO, Inc. 1 After RubyKaigi 2025〜ZOZO、ファインディ、ピクシブ〜
© ZOZO, Inc. 株式会社ZOZO ブランドソリューション開発本部 WEARバックエンド部 バックエンドブロック 小山 慧 •
2019年4月 株式会社ZOZOに新卒入社 ◦ WEARのバックエンド開発を担当 ◦ RubyKaigiは今年4回目! 2
© ZOZO, Inc. https://wear.jp/ 3 • あなたの「似合う」が探せるファッションコーディネートアプリ • 1,800万ダウンロード突破、コーディネート投稿総数は1,400万 件以上(2024年12月末時点)
• コーディネートや最新トレンド、メイクなど豊富なファッション 情報をチェック • AIを活用したファッションジャンル診断や、フルメイクをARで試 せる「WEARお試しメイク」を提供 • コーディネート着用アイテムを公式サイトで購入可能 • WEAR公認の人気ユーザーをWEARISTAと認定。モデル・タレン ト・デザイナー・インフルエンサーといった各界著名人も参加
© ZOZO, Inc. 4 RubyKaigi今年も最高でした!!!
© ZOZO, Inc. 5 スポンサーブースやお昼ご飯が豪華!
© ZOZO, Inc. 6 ドリンクアップなどを通じて社内外の方々と交流もできました! • 社外の人とたくさん話せました! ◦ @Findy Drinkup
at RubyKaigi 2025 ◦ ドリンクアップで知り合った方々とランチも • 社内の交流も深まりました! ◦ みかんジュース飲み比べ ◦ 松山城観光
© ZOZO, Inc. 今回のテーマは「型」 RubyKaigi 2025を機にRubyの型に入門した初心者です
© ZOZO, Inc. 8 今日話す内容 • RBSとrbs-traceについて • rbs-traceを試してみたいと思った背景 •
rbs-traceをWEARで試してみた
© ZOZO, Inc. 9 RBSとは • Rubyのプログラムの型情報を記述するための言語 • Ruby 3.0から標準ライブラリとして同梱されている
• 型定義は.rbsファイルとして、.rbファイルから独立して管理される ◦ 型情報を記述することで、動的型付け言語であるRubyの柔軟性を維持しつつ、静 的型チェックの恩恵を得られる
© ZOZO, Inc. 10 RBSの記述方法 • 型定義専用の.rbsファイルに記述する方法 • rbs-inlineというgemを用いて、.rbファイル内のコメントとして型定義を記述する方法 ◦
YARDのような形式 ◦ rbs-inlineコマンドで、.rbsファイルが生成できる ◦ 将来的にはrbs gemにマージされる予定
© ZOZO, Inc. 11 rbs-inlineの埋め込み型の型宣言がされた.rbファイル 引用元:https://github.com/soutaro/rbs-inline .rbファイル # rbs_inline: enabled
class Person attr_reader :name #: String attr_reader :addresses #: Array[String] # @rbs name: String # @rbs addresses: Array[String] # @rbs return: void def initialize(name:, addresses:) @name = name @addresses = addresses end # @rbs () -> String def to_s "Person(name = #{name}, addresses = #{addresses.join(", ")})" end end
© ZOZO, Inc. 12 rbs-inlineから生成される.rbsファイル 引用元:https://github.com/soutaro/rbs-inline .rbsファイル class Person attr_reader
name: String attr_reader addresses: Array[String] def initialize: (name: String, addresses: Array[String]) -> void def to_s: () -> String end
© ZOZO, Inc. 13 rbs-traceとは • Rubyの標準ライブラリであるTracePointを活用して、テスト実行時に型情報を収集 • .rbファイル内にrbs-inline用の埋め込み型の型宣言として自動的に挿入してくれる •
.rbsファイルも自動的に生成してくれる
© ZOZO, Inc. 14 rbs-traceを試してみたいと思った背景 • 例年、RBS関連のセッションが多く、注目が集まっているため • 型の恩恵を感じてみたかったため ◦
LSPによる開発体験の向上 ◦ Steepによる静的型検査で型安全を担保出来ること • Rubyで型を自動生成するアプローチが様々登場してきている中で、その1つを試してみたかったた め ◦ rbs-trace ◦ rbs prototype ◦ rbs-inline ◦ rbs_rails ◦ orthoses ◦ sord ◦ Tapioca & Spoom ◦ RBS Goose ◦ etc. • WEARではテストコードを書く文化が根付いているので親和性が高いと感じたため
© ZOZO, Inc. rbs-traceをWEARで試してみた
© ZOZO, Inc. 16 環境 • ruby: 3.3.6 • Rails:
6.1.7.10 • rbs: 3.9.2 • rbs-trace: 0.51 • steep: 1.10.0 • VS Code: 1.99.3
© ZOZO, Inc. 17 rbs-traceの導入方法 1. rbs-trace をGemfileへ追加 2. bundle
install 3. RSpecに統合するため spec/support/rbs_trace.rb を作成して次のページのコードを 追加 a. 今回はLSPの恩恵を得るためにsteep checkも通したかったので、対象を app/models/coordinate.rb に絞った 引用元:https://github.com/sinsoku/rbs-trace
© ZOZO, Inc. 18 rbs-traceの導入方法 RSpec.configure do |config| # RBSの出力対象とするファイルを指定
trace = RBS::Trace.new(paths: Dir.glob("#{Dir.pwd}/app/models/coordinate.rb")) config.before(:suite) { trace.enable } config.after(:suite) do trace.disable trace.save_comments # RBSファイルの格納先を指定 trace.save_files(out_dir: "sig/trace/") end end
© ZOZO, Inc. 必要な準備はこれだけ!
© ZOZO, Inc. 20 RSpec実行 • bundle exec rspec spec/models/coordinate_spec.rb
© ZOZO, Inc. 21 出力結果を確認 • app/models/coordinate.rb にインラインコメントで @rbs のシグネチャが付与された
• sig/trace/app/models/coordinate.rbs が生成されて、RSpecから呼び出された対象の クラスとメソッドの型が生成された • 107個あるメソッドのうち79個に対して型が付いた! ◦ テスト時に実行されさえすればprivateメソッドであっても型情報が生成された
© ZOZO, Inc. 22 rbs-traceを実運用する上での課題 • テスト内で実行されないメソッドには型が付かない • ArrayやHashといったコレクションオブジェクトの中身はuntypedで定義される •
型が正しく定義されているかの確認が大変 ◦ WEARのRailsアプリにはYARDが既に記述されているので、今回はYARDと見比べ て確認をした • テスト実行の度に.rbsファイルはすべて新しく作り直される • .rbファイルのメソッドの引数や戻り値を変更した後にテストを実行した場合であって も.rbファイル内のインラインRBSコメントが更新されない ◦ .rbsファイルと.rbファイル内のインラインRBSコメントの型とで乖離が起こる
© ZOZO, Inc. 23 VS Code拡張のSteepを導入
© ZOZO, Inc. 24 Steepとは • Rubyプログラムの静的な型検査を行うためのgem • LSPの機能も内包しており、SteepのLSPサーバーは.rbsファイルに記述された型情報 と、.rbファイルの実際のRubyコードを照らし合わせることでエディタに対して以下の
ような機能を提供する ◦ コード補完 ◦ エラーハイライト ◦ 型情報の表示 ◦ 定義ジャンプ
© ZOZO, Inc. 25 Steepの導入 1. steep をGemfileへ追加 2. bundle
install 3. bundle exec steep init を実行してSteepfileを生成
© ZOZO, Inc. 26 steep check実行前の準備 1. rbs collection init
を実行 2. rbs collection install を実行してgemのRBSシグネチャを取得してくる 3. Steepfileに次のページの設定を記述
© ZOZO, Inc. 27 Steepfile D = Steep::Diagnostic target :app
do # RBSファイルの格納先を指定 signature "sig/trace/app/models/coordinate.rbs" # Steepで型チェックする対象のファイルを指定 check "app/models/coordinate.rb" configure_code_diagnostics(D::Ruby.silent) end 引用元:https://github.com/soutaro/steep/blob/v1.10.0/manual/ruby-diagnostics.md
© ZOZO, Inc. 28 steep check実行 • bundle exec steep
check を実行して静的型検査を行う
© ZOZO, Inc. 29 steep checkの結果を確認 • rbs_collectionに存在しないgemの型定義や、今回はrbs-traceで1つの.rbsファイルし か生成していない関係で他の自作クラスの型定義がないため、Cannot find
typeエ ラーが発生した • Cannot find typeエラーに対しては、今回は、steep checkを通すため全てuntypedに 置き換えることで対応した
© ZOZO, Inc. 30 steep checkを再度実行 • 無事にNo type error
detected.になった!
© ZOZO, Inc. 31 LSPの恩恵を受けることができた(コード補完)
© ZOZO, Inc. 32 LSPの恩恵を受けることができた(エラーハイライト)
© ZOZO, Inc. 33 Steepによる静的型検査で型安全を担保 • Ruby.silentでの実行のため未達成 • 先述の通り、Ruby.silentであったとしても、Cannot find
typeエラーは発生する • 存在しない型定義についてはuntypedを明示してエラーを避けるか、自前でシグネ チャを記述するなどの対応が必要なため、Steepで型検査を行うのは実際の運用を考え ると手間がかかりそう • untypedが多くなってしまうと型安全性は弱くなる
© ZOZO, Inc. 34 今後試してみたいこと • rbs-traceで初回の型付けを実行した後にrbs-inlineを使って型定義を運用していくと いうイメージが付いたので、実践してみたい • Ruby.silentではなくRuby.lenientなどを使い段階的に型安全性を高めたい
• 今回は試せなかったが、WEARはyardを書く文化もあるので、yardから型生成してく れるsordというgemも試してみたい
© ZOZO, Inc. 35 RubyKaigiを振り返って • SorbetがRBSファイルのパースに取り組んでいたり、rbs-inlineがrbsの標準になる動 きがあるなど、型周りのエコシステムが統合されつつある印象でした! • RBS周りは進化が早いので今後も動向を追っていきたいです!
None