Slide 1

Slide 1 text

2023/11/15 正徳巧 Railsアプリと型検査 @sinsoku @sinsoku_listy

Slide 2

Slide 2 text

自己紹介 ● 名前: 正徳 巧(aka: 神速) ● 部署: CTO室 ● 入社月: 2022年11月(社歴1年) ● 好きな言語: 🦀Rust, 💎Ruby ● Rails歴: 8年くらい @sinsoku @sinsoku_listy

Slide 3

Slide 3 text

タイミーの実績 スキマ バイト No.1 ※203年10月時点 ※1 [調査方法]デスクリサーチ及びヒアリング調査 [調査期間]2021年2月8日~22日 [調査概要]スキマバイトアプリ サービスの実態調査 [調査対象]2020年12月までにサービスを開始しているスキマバイトアプリ10サービス [調査実施]株式会社ショッ パーズアイ ※2 [出典]AppStoreライフスタイルカテゴリーランキング(2021年5月時点) 3 累計求人案件数 ・ダウンロード数 ※1 ※2 導入事業者数 66,000企業 ワーカー数 600万人

Slide 4

Slide 4 text

興味を持った人は橋本環奈さんのCMをどうぞ 📦「タイミー CM」 で検索


Slide 5

Slide 5 text

目次 ● RBSの基本 ● 弊社の導入事例を紹介 ● 型検査の課題

Slide 6

Slide 6 text

1 RBSの基本

Slide 7

Slide 7 text

RBSとは Rubyで型を定義するための言語。

Slide 8

Slide 8 text

RBSとは ● 拡張子は `*.rbs` で sig/ ディレクトリに置く ○ つまりRubyとは別ファイル ● 主な利用方法は2つ ○ 型検査 ○ 入力補完

Slide 9

Slide 9 text

型検査(Steep) RBSの定義に違反しているコードを検出するツール。

Slide 10

Slide 10 text

型検査(Steep)の実行例 RBS Ruby

Slide 11

Slide 11 text

型検査(Steep)の実行例 Rubyを実行する前にエラーに気づくことができる

Slide 12

Slide 12 text

入力補完(VS Code)の実行例 `soutaro.steep-vscode` の拡張で入力補完が賢くなる

Slide 13

Slide 13 text

入力補完(IRB) IRB v1.9.0(2023-11-11)でRBSを使った入力補完がサポートされました

Slide 14

Slide 14 text

入力補完(IRB)の実行例 入力補完でRBSが使用される

Slide 15

Slide 15 text

2 弊社の導入事例を紹介

Slide 16

Slide 16 text

RBSの導入を検討(2023-05) ● ⭐RubyKaigi 2023、メドピアのブログで意欲が高まる ○ Railsプロジェクトへの「頑張らない型導入」のすすめ ○ https://tech.medpeer.co.jp/entry/2023-small-rbs-introduce ● 🐤RBSの導入を試したら容易だった ○ 型検査エラーを無視する ○ `rbs prototype rb` でRBSを生成する ● ❤型は重要なところをだけYARDで書きたい ○ 弊社の開発者は誰も `*.rbs` を手書きしたくなかった ○ YARD -> RBS が実現できることが分かった ● ⛏RBSは書かずに生成するので、Gitでは管理しない 💪本番影響もないので、試しに導入を進めてみた

Slide 17

Slide 17 text

RBS + Steepを導入 1. rbs_rails, steep をGemfileに追加する。

Slide 18

Slide 18 text

RBS + Steepを導入 2. Steepfileを追加し、既存の型検査エラーは無視する。

Slide 19

Slide 19 text

RBS + Steepを導入 3. `rbs_collection.yaml` を作成する

Slide 20

Slide 20 text

RBS + Steepを導入 4. RBSを生成するRakeタスクを追加する。

Slide 21

Slide 21 text

RBS + Steepを導入

Slide 22

Slide 22 text

RBS + Steepを導入 5. `.gitignore` でディレクトリを無視する

Slide 23

Slide 23 text

RBS + Steepを導入 6. RBSの定義エラーを回避するために最小限の型を書く

Slide 24

Slide 24 text

この時点でできること ● `bin/rails rbs:setup` を実行すると sig/ にRBSが生成される ○ クラスやメソッドに対応する型定義が生成される ○ メソッドの戻り値のほとんどは untyped になる ● steep check は実行できる ○ 型検査エラーはほぼ全てを無効化 ○ RBSの定義エラーを検出するため、 CIで `steep validate && steep check` は実行する ● 入力補完で型を活用できる状態になっている ○ 開発者は `bin/rails rbs:setup` を実行すれば良い ⭐RBSを1行も書かなくても入力補完に型を使用できる

Slide 25

Slide 25 text

Sordを導入 1. sordをGemfileに追加する

Slide 26

Slide 26 text

Sordを導入 2. Rakeタスクでsordも実行する

Slide 27

Slide 27 text

RBS + Sord の導入が完了 ● `bin/rails rbs:setup` を実行するとRBSが生成される ○ YARDを書くと sig/sord/generated.rbs に反映 ○ YARD以外は sig/prototype/**/*.rbs に反映 ○ ActiveRecordのメソッドは sig/rbs_rails/app/models/*.rbs に反映 ● RubyMineやVS Codeだと入力補完が良くなる(らしい) ○ 私はVimユーザーで、実はあまり詳しくない 🙈 ○ 懇親会で弊社の開発者を捕まえて聞いて欲しい 👀

Slide 28

Slide 28 text

既知の課題や検討事項 ● 😅`bin/rails rbs:setup` を実行するのが面倒 ○ コード書いたら自動的に反映されて欲しい ○ ただ、差分更新するには Rakeタスクの実装を見直す必要がある ● ⏳RBSの生成に時間がかかる ○ 約40秒 ○ 削除して再生成しているため無駄がある ● 🎃 sig/app.rbs が手書き ● 🤔 ksss/orthoses への移行を検討 ○ sord は1ファイルだけど orthoses-yard は複数ファイルに出力できる ○ 差分更新には都合が良い 🍻この辺りの話を聞きたい人は懇親会で声かけて

Slide 29

Slide 29 text

3 型検査の課題

Slide 30

Slide 30 text

🔥型検査の課題 ● gemの型定義が少ない ○ gem_rbs_collection には一部gemの型しか存在しない ○ 型が不十分なので、型検査の精度が悪い ● 型検査エラーを部分的に無視できない ○ rubocop_todo.yml みたいなものが作れない ○ 段階的な導入が難しい

Slide 31

Slide 31 text

💣弊社での型検査のエラー数 型定義の不足や誤検知で多数のエラーが検知される

Slide 32

Slide 32 text

😇まだ誤検知が多い validate メソッドは使えるはずだけど、エラーになってしまう。 我々のRBSの定義ミスなのか、それともRBSやSteepのバグなのか。

Slide 33

Slide 33 text

👻型検査で見つけたコード例 ※ 上記は説明用のコードで、実際のプロダクトコードとは異なります。

Slide 34

Slide 34 text

✅まとめ ● RBSで入力補完が賢くなる ○ 既に実用的な状況になっている ● Railsアプリ開発で型検査を使う ○ 現状はまだ実用的とは言い難い ○ 今後の開発に期待 OSSコントリビュートチャンス🌱 ぜひ明日からRBSを導入して、触ってみましょう!💎