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
Type on Rails - Railsアプリケーションの安全性と開発体験を型で革新する
Search
kazzix
October 26, 2024
5
1.1k
Type on Rails - Railsアプリケーションの安全性と開発体験を型で革新する
kazzix
October 26, 2024
Tweet
Share
More Decks by kazzix
See All by kazzix
プログラミング言語Rustのすすめ @TwoGate Tech Meeting
kazzix
0
220
Featured
See All Featured
Fashionably flexible responsive web design (full day workshop)
malarkey
405
66k
What's in a price? How to price your products and services
michaelherold
243
12k
Designing for Performance
lara
604
68k
The Invisible Side of Design
smashingmag
298
50k
VelocityConf: Rendering Performance Case Studies
addyosmani
326
24k
Practical Orchestrator
shlominoach
186
10k
Raft: Consensus for Rubyists
vanstee
137
6.7k
Side Projects
sachag
452
42k
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.9k
Writing Fast Ruby
sferik
628
61k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
26
1.9k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
38
1.9k
Transcript
2024/10/26 Type on Rails Railsアプリケーションの 安全性と開発体験を型で革新する Kaigi on Rails 2024
村田 一真 @kazzix14
Kazuma Murata @kazzix14, @kazzix 好きなもの:プログラミング言語・音楽など Rust:8年〜 Rails: 5年〜 ギター: 12年〜
ポーカー楽しい 2/47
株式会社TwoGate 3/47
TRIPLE イベント会場向けの モバイルオーダーアプリ チケットシステム オンラインガチャサービス 4/47 累計220万DL / 100万ユーザ登録
イベント会場向けの モバイルオーダーアプリ チケットシステム オンラインガチャサービス 5/62 TRIPLE
ブース・ドリンクアップで話しましょう 5/47
話すこと 9 型システム導入の利& 9 ドキュメントにない部4 9 実際に導入してみÉ 9 型を生かした設計・実装 話さないこと
9 理h 9 ドキュメントにあるような手順の詳I 9 実装の詳細
目次 P 型システム導入の動機・利1 P RBI・Sorbet・Tapiocaの紹D P Sorbetの導入手 P 実際に導入するためのG P
型システムを活かした設計・実装 6/47
型システム導入の動機 1 コード上の問題を早期に発' 1 安全& 1 開発体 1 開発速度 7/47
もっと気持ちよく、Railsを書きたい 抽象的な話だけだと分かりづらいので 8/47
9/62 u 式の意味が一目でわかA u コードジャンプ(Go To Definition, Go To Reference'
u 意図しない動作の変化に気づけA u 補完がされA u 意図しないシステムへの入力に気付けA u より構造化されたプログラムが書きやすい 9/47
やってみて気づくであろうところ 後から変数名やメソッド名を変えた時の変更漏 以外にnil考慮漏れが多 型の考慮漏 値の考慮漏れ 10/47
11/47 やってみて気づくであろうところ
デモ
Challenges Without Types f 実行しないと問題が機械的にわからなI f テストが漏れていれば検知できなI f コードベースのキャッチアップに時間がかか1 f
「3日前の自分は他人# f 補完が効きづらくタイプ量が増える 16/47
エラーが早く出るとそれだけ開発が早くなる 6A 設8 4A 実1 7 ここでエラーに気付け #A テスB A
検 )A ... 17/47
目次 I 型システム導入の動機・利% I RBI・Sorbet・Tapiocaの紹) I Sorbetの導入手É I 注意点・工Ç I
型システムを活かした設計・実装 18/47
RBI (RuBy Interface) D 型定義用のDS3 D Rubyのサブセッ# D Rubyの中にも、別のファイルにも書ける Sorbet
D RBIのための型検査c D Strip` D ランタイムがある Tapioca D RBI・Sorbetの補助ツー D Shopify 19/47
RBS・Steepについてここでは話しません 型定義 RBI RBS Steep Sorbet 型検査器 Tapioca 補助 20/47
RBI・Sorbetをなぜ採用し たのか @ 信頼E @ ShopifyやStripeによる実d @ 型検査の速度が早i @ LSPでリアルタイムに型検査の結果がわかr
@ CIも数万行のコードベースに対して数S @ 型定義がファイル内にかける* *rbs-inlineなども今はある 21/47
Tapiocaについて e Gemの型生T e 依存Gemからの型読み込G e リモートにあるRBIの取7 e その他RBIの管F e
Tapioca DSL CompilerではRubyを実際に読み込んで型を生成する 22/47
目次 I 型システム導入の動機・利# I RBI・Sorbet・Tapiocaの紹' I Sorbetの導入手É I 注意点・工Ç I
型システムを活かした設計・実装 23/47
Sorbetの導入手順 5 Gemの追" ( Tapioca Ini エラーの修正 https://sorbet.org/docs/adopting 24/47
かなり充実している
https://sorbet.org 24/47 公式ドキュメントが充実!
エラーの修正について q エラー番号があY q 公式ドキュメントのError Referenceを見て直していく E q いままで導入できなかったことはなT q
主要プロダクトの7割ぐらいは型がついている 25/47
Code LOC 13k, モデル173 Code LOC 14k, モデル数159 Code LOC
24k, モデル数252 実際導入した時のDiff RBIのdiff抜き(ファイル数にはカウント) 26/47 慣れれば、モデル数200以下ぐらいなら2、3日ぐらい?
型がつくようになった 27/47
目次 I 型システム導入の動機・利# I RBI・Sorbet・Tapiocaの紹' I Sorbetの導入手É I 注意点・工Ç I
型システムを活かした設計・実装 28/47
注意点・工夫など Sorbetを実際に導入するにあたって 29/47
SorbetのStrictness levelについて ファイル単位で指定できる 8 ignor6 8 fals6 8 tru6 8
stric1 8 strong 最初は、基本trueかfalseがおすすめ 30/47
ランタイムの型エラーで例外をあげない Sentryに通知して握りつぶすことで検知しつつ動作を変えない 31/47
LSPでエディターからSorbetを動かす Sorbet bundle exec srb tc --lsp Docker Network Editor
・・・ Imageは同じ LSP 32/47 Ruby LSP Ruby LSPも動くと便 RuboCo オートフォーマット
CIでチェックする a sorbet tE a 型チェック(Type Check9 a tapioca dsl
--verify, tapioca gems --verifS a 自動生成したRBIが正しい a tapioca check-shimA a RBIに重複がないか 33/47
目次 I 型システム導入の動機・利# I RBI・Sorbet・Tapiocaの紹' I Sorbetの導入手É I 注意点・工Ç I
型システムを活かした設計・実装 34/47
型は内側からつけていく GD lib/, app/lib8 7D ModeA )D (あるなら)Service, FormObjec D
Controller よく使われるメソッド・自明ではないメソッドから型をつけs Q 効果・恩恵が大きい 37/47
具体的になにをするか H@ まずはuntypedを減らI W@ if文で条件分岐するのではなく、性質ごとに分けた型と パターンマッチングを使& 考慮漏れを静的に検知でき6 b@ 例外の代わりにResult型を使う つまり、できるだけ値を意識しなくて済むコードにする
=型が同じなら動作・扱いは同じ 38/47
Introduction to Tapioca DSL Rubyを実行して動的に型を生成する仕組み 34/47
Tapioca DSL Compiler E DSL Compilerは単一のものではなく仕組2 E Rubyを実際に読み込んで型を生成す E 簡単に実装できる
3 DSL Compiler 35/47 生成対象のClass, Moduleの選択 生成対象のClass, Moduleを実際に参照して型生成をRubyでできる 1 concern 2 model
かなりの数のDSL Compilerが実装されている Railsで使うようなものは大体網羅 d path_helpea d associatioH d ModelのカラW d
など...
Tapioca DSL によりかなり柔軟に型がつけられる 36/47
具体例 37/47
enumに型をつける パターンマッチで条件分岐の漏れを検知できる 39/47
Model enumに型をつける 52/62 使用例 enumerizeにパッチを当て、Tapioca DSL Compilerを書くことで、網羅性検証を可能に
後からステータスが増えた場合などに特に有用 52/62 Model 使用例
例外の代わりにResult型を使う 41/47 中身を読まないと失敗することがわからない Result型にする
ResultとはÅ É 成功か失敗を示す型 成功か失敗かがわからないと中身が取り出せない 型定義のイメージ →中身を取り出すためにエラーのハンドリングを強制できる 42/47
例外の代わりにResult型を使う 中身を読まないと失敗することがわからない 中身を読まなくても失敗することがわかる 43/47
44/47 F 現4 F Result7 F Option7 F 直和7 F
Sealed Subclassesによるエミュレート。Scalaと同じ手C F 色々足したい Result型はSorbetにはない Result型やその他便利な型などを定義するGem、mangroveを作った
こういったテクニックを 組み合わせていく 8 コード上の問題を早期に発4 8 安全3 8 開発体$ 8 開発速度
45/47 話せていないこと、これからやりたいことも多い
まとめ I 型システム導入の動機・利! I RBI・Sorbet・Tapiocaの紹% I Sorbetの導入手É I 実際に導入するためのD I
型システムを活かした設計・実装 46/47
ありがとうございました 62/62