入社数ヶ月のnewbieが 稼働7年超のプロジェクトに 型を導入して見えた世界
by
Fu-ga
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
Kaigi on Rails 2022 - 10.22(Sat) 入社数ヶ月のnewbieが 稼働7年超のプロジェクトに 型を導入して見えた世界 ふーが@fugakkbn / ESM, Inc
Slide 2
Slide 2 text
Profile ふーが @fugakkbn 2022年3月からエンジニアに(at ESM, Inc) Railsを使用したアプリケーション開発 gem_rbs_collectionのコントリビューター プロジェクトへの型導入を進めている Kaigi on Rails Organizer
Slide 3
Slide 3 text
動機 なぜ型に興味を持ったのか? 初めての型 TypeScriptで静的型に初 めて触れ、型があること のメリットを知った。 Rubyでも型の恩恵を 3.0からRubyでも静的型 を扱えるようになった が、プロジェクトには導 入されていなかった。 後押し 1on1でEMに「型に興味 がある」話をしたら「プ ロジェクトに導入してみ たら?」
Slide 4
Slide 4 text
No content
Slide 5
Slide 5 text
×
Slide 6
Slide 6 text
コミュニティとの ”共生” このワードにピンと来た方は… @fugakkbn or agile.esm.co.jp まで!!
Slide 7
Slide 7 text
No content
Slide 8
Slide 8 text
Kaigi on Rails 2022 - 10.22(Sat) 入社数ヶ月のnewbieが 稼働7年超のプロジェクトに 型を導入して見えた世界 ふーが@fugakkbn / ESM, Inc
Slide 9
Slide 9 text
アジェンダ newbieこそ型定義をするべき どのように導入を提案したか 導入する上での障壁
Slide 10
Slide 10 text
今日伝えたいこと newbie の皆さん 型情報から得られるフィードバック以外にもたくさんのメ リットがあることを知って欲しい もし型に興味を持ってもらえたなら、ぜひプロジェクトへ の導入を! 先輩の皆さん 同僚から型導入の打診があった時は今日紹介するようなメ リットを思い出して、ぜひ導入の支援をお願いします!
Slide 11
Slide 11 text
RBSの文法、書き方 導入の具体的な手順
Slide 12
Slide 12 text
用語の紹介 基本的なものだけ紹介 RBS Rubyの型を書くための言 語の名称。Ruby Likeな 書き方ができるため理解 やすい。 Steep Rubyの静的型解析機。 steep checkコマンドで Rubyファイルとrbsファ イルの型検査ができる。 ジェネレーター この発表では「プロダク トコードをもとにRBSの コードを自動生成するも の」として話します。
Slide 13
Slide 13 text
newbieこそ型定義をするべき https://unsplash.com/ja/%E5%86%99%E7%9C%9F/ak4hw4r6xio
Slide 14
Slide 14 text
なぜ? 理由はいくつかあります コードを読み解きやすくなる プロジェクトの全容把握の近道になる 実装を読むことへの抵抗がなくなる 無限にコントリビュートチャンスがある
Slide 15
Slide 15 text
なぜ? 理由はいくつかあります コードを読み解きやすくなる プロジェクトの全容把握の近道になる 実装を読むことへの抵抗がなくなる 無限にコントリビュートチャンスがある
Slide 16
Slide 16 text
皆さんに質問 プロジェクトに全部でいく つのメソッドが定義されて いますか? また、それらの引数にはど んな値が入りますか?
Slide 17
Slide 17 text
とあるアプリのメソッド数
Slide 18
Slide 18 text
とあるアプリのメソッド数
Slide 19
Slide 19 text
すべてを覚えておくのはムリ! 一度読んで理解してもしばらくしたら忘れてしまう 先輩のコードをレビューしているとき、テストコードを読み解くとき、障害発生 時に調査するとき…などなど、折に触れてメソッドの構造を理解するべきタイミ ングがあると思います。
Slide 20
Slide 20 text
そこで型ですよ 型があれば覚えておく必要がない なぜなら型を見ればどんな引数を渡してどんな返り値なのかが一目でわかるから 「これってどういうメソッドなんだっけ?」から始まる調査の手間は決して軽い ものではないはず。
Slide 21
Slide 21 text
rbsファイル アプリケーションコード
Slide 22
Slide 22 text
rbsファイル アプリケーションコード
Slide 23
Slide 23 text
rbsファイル 違う型を引数に渡そうとすると…
Slide 24
Slide 24 text
rbsファイル 型が違うことを教えてくれる!
Slide 25
Slide 25 text
型をつけたことで たくさんあるメソッドを 読み解きやすくなった
Slide 26
Slide 26 text
型をつけたことで たくさんあるメソッドを 読み解きやすくなった 型
Slide 27
Slide 27 text
なぜ? 理由はいくつかあります コードを読み解きやすくなる プロジェクトの全容把握の近道になる 実装を読むことへの抵抗がなくなる 無限にコントリビュートチャンスがある
Slide 28
Slide 28 text
プロジェクトの 全容把握 newbieな僕の最初の壁 その1
Slide 29
Slide 29 text
newbie 心の叫び どこに何が定義され ているのかわからな い。モデル同士の関 連どうなってるの? 「簡単な修正」って issue 振ってもらっ たけど…どこから手 をつければいいの? メソッドの処理が複 雑すぎて最終的にど うなるのかわから ん!!! コードジャンプ候補 に同名メソッドがた くさん出てきてどれ が正しいのかわから ない。。。
Slide 30
Slide 30 text
newbie 心の叫び どこに何が定義され ているのかわからな い。モデル同士の関 連どうなってるの? 「簡単な修正」って issue 振ってもらっ たけど…どこから手 をつければいいの? メソッドの処理が複 雑すぎて最終的にど うなるのかわから ん!!! コードジャンプ候補 に同名メソッドがた くさん出てきてどれ が正しいのかわから ない。。。
Slide 31
Slide 31 text
そこで型ですよ 型を書くことで理解が深まる 型を書くにはメソッドの使い方や使用時の挙動を調査する必要がある。 それを繰り返す中でどんどんわかることが増えていき、プロジェクトへの理解が 深まっていく。
Slide 32
Slide 32 text
型定義を進めるために嫌でもプロジェクト内のファイルを横 断的に見ることになる モデル同士の関連がどうなっているか理解が進んだり、この モデルにこんなメソッドがあるのか!などの発見がある それらに型付けする過程でユースケースやどこで使われてい るのかなどが自然とわかる
Slide 33
Slide 33 text
別のメリット 今後の自分の助けにもなる 型付けが進むとIDEの補完の正確度が上がる。正確度が上がると調査 も実装も速度が上がるため、相対的に同じ時間内で得られる情報量 が増える。
Slide 34
Slide 34 text
補完候補(型がない場合)
Slide 35
Slide 35 text
補完候補(型がない場合)
Slide 36
Slide 36 text
補完候補(型がある場合)
Slide 37
Slide 37 text
補完候補(型がある場合)
Slide 38
Slide 38 text
nextメソッドの定義を見たい!
Slide 39
Slide 39 text
ここでコードジャンプしようとすると…
Slide 40
Slide 40 text
候補がたくさん表示されてしまう
Slide 41
Slide 41 text
型をStringだと定義しておくと…
Slide 42
Slide 42 text
一発で String#next の定義元に飛べる!
Slide 43
Slide 43 text
型をつけたことで プロジェクトへの理解が進み 調査や実装もしやすくなった
Slide 44
Slide 44 text
型をつけたことで プロジェクトへの理解が進み 調査や実装もしやすくなった 型
Slide 45
Slide 45 text
なぜ? 理由はいくつかあります コードを読み解きやすくなる プロジェクトの全容把握の近道になる 実装を読むことへの抵抗がなくなる 無限にコントリビュートチャンスがある
Slide 46
Slide 46 text
gemの実装を見るのが苦手 newbieな僕の最初の壁 その2
Slide 47
Slide 47 text
苦手な理由 思い返してみると… 難しいコードがたくさん出てくる印象 どこから見ればいいのかわからない 「まだ自分には読めない」という先入観
Slide 48
Slide 48 text
型生成プロセス 良いサイクルが生まれます 調査 メソッドの構造 (引数の型、返 り値の型)や使 われ方を調査す る。 型定義 調査結果をもと に型を定義して いく。このとき gem の型定義 の不足や誤りが 判明することも 実装の確認 起こっているエ ラーが型定義の 誤りなのかそう でないのかは、 gem の実装を 見る必要がある 反復 型定義はこれら の繰り返し。繰 り返しやってい るうちに実装を 見るのが日常に なる。 成果物 プロジェクトの 型定義はもちろ ん、場合によっ ては OSS にコ ントリビュート できることも。
Slide 49
Slide 49 text
steep checkで出たエラーに疑義がある場合 gemの型定義がなくて追加しようとするとき
Slide 50
Slide 50 text
steep check 実行時に見つかる
Slide 51
Slide 51 text
steep check 実行時に見つかる
Slide 52
Slide 52 text
steep check 実行時に見つかる
Slide 53
Slide 53 text
steep check 実行時に見つかる
Slide 54
Slide 54 text
実装元を確認する
Slide 55
Slide 55 text
Receive block!
Slide 56
Slide 56 text
gemの実装を見ることが "日常"になった。 あの頃の苦手意識はもうない
Slide 57
Slide 57 text
gemの実装を見ることが "日常"になった。 あの頃の苦手意識はもうない 型
Slide 58
Slide 58 text
gemの実装を見ることが "日常"になった。 あの頃の苦手意識はもうない 型 ※ただし読めるとは言っていない
Slide 59
Slide 59 text
なぜ? 理由はいくつかあります コードを読み解きやすくなる プロジェクトの全容把握の近道になる 実装を読むことへの抵抗がなくなる 無限にコントリビュートチャンスがある
Slide 60
Slide 60 text
OSSって なにから始めればいいの? newbieな僕の最初の壁 その3
Slide 61
Slide 61 text
OSS
Slide 62
Slide 62 text
OSS 選ばれし人がやること 初心者の自分にできるわけがない。技術に秀でたすごい人 たちがやること。
Slide 63
Slide 63 text
OSS 選ばれし人がやること 初心者の自分にできるわけがない。技術に秀でたすごい人 たちがやること。 自分にできることがあるはずない すごい技術を持った人たちが作ったものに自分が修正でき るところがあるわけない。
Slide 64
Slide 64 text
OSS 選ばれし人がやること 初心者の自分にできるわけがない。技術に秀でたすごい人 たちがやること。 自分にできることがあるはずない すごい技術を持った人たちが作ったものに自分が修正でき るところがあるわけない。 やってみたい気持ちはあるけれど… どこから手をつけたらいいのか、どこが修正すべきところ なのか、どうやってパッチを送ればいいのかナニモワカラ ナイ。
Slide 65
Slide 65 text
型定義を始めるまでは…
Slide 66
Slide 66 text
型定義の誤り
Slide 67
Slide 67 text
gemの型定義の不足
Slide 68
Slide 68 text
試行錯誤の中での気づき プロジェクトの型導入をしている中で gemの型定義が足りなかったり間違ってることがあるなぁ
Slide 69
Slide 69 text
試行錯誤の中での気づき プロジェクトの型導入をしている中で gemの型定義が足りなかったり間違ってることがあるなぁ これってもしや…コントリビュートチャンスってやつ!?
Slide 70
Slide 70 text
OSSへの初めてのコントリビュート
Slide 71
Slide 71 text
No content
Slide 72
Slide 72 text
コントリビュートは すごい人だから するものではない。 「使ってる人が 気付いた時にするもの」
Slide 73
Slide 73 text
コントリビュートは すごい人だから するものではない。 「使ってる人が 気付いた時にするもの」 型
Slide 74
Slide 74 text
なぜ? 理由はいくつかあります コードを読み解きやすくなる プロジェクトの全容把握の近道になる 実装を読むことへの抵抗がなくなる 無限にコントリビュートチャンスがある
Slide 75
Slide 75 text
興味を持ってもらえたら プロジェクトに型を 導入してみてください! newbieの多くの悩みを解決してくれます
Slide 76
Slide 76 text
とはいえ…
Slide 77
Slide 77 text
newbieに型を導入する 裁量なんてないんですが!?
Slide 78
Slide 78 text
どのように 型導入を提案したか https://unsplash.com/ja/%E5%86%99%E7%9C%9F/5Q07sS54D0Q
Slide 79
Slide 79 text
小さく少しずつ
Slide 80
Slide 80 text
第1ステップとして、rbs, rbs-rails, gem_rbs_collection などで大枠の型定義をそろえる
Slide 81
Slide 81 text
第1ステップとして、rbs, rbs-rails, gem_rbs_collection などで大枠の型定義をそろえる 第2ステップとして、生成された rbs ファイルの untyped を 正しい型に書き換えていく
Slide 82
Slide 82 text
第1ステップとして、rbs, rbs-rails, gem_rbs_collection などで大枠の型定義をそろえる 第2ステップとして、生成された rbs ファイルの untyped を 正しい型に書き換えていく 並行して、steep check でのエラーから gem の型定義不足 や誤りを見つけて修正する
Slide 83
Slide 83 text
gemもrbsも独立しているので剥がすのは簡単 主要なModelやAPIだけでもよい 型があってもなくてもプロダクトコードに影響はない Linterで警告が出たりノイズが発生することもない
Slide 84
Slide 84 text
CIには入れない
Slide 85
Slide 85 text
エラーの解消が目的ではない 目的はあくまで"開発者体験の向上" CIに組み込むと間違いなくエラーが出続ける CIがずっとredだと"オオカミ少年"状態になる… 型のエラーを検知したい訳ではない プロジェクト内の型を充実させることに集中する方が建設的
Slide 86
Slide 86 text
書きたい人だけ
Slide 87
Slide 87 text
型を書きたい人
Slide 88
Slide 88 text
型を書きたい人
Slide 89
Slide 89 text
型を書きたい
Slide 90
Slide 90 text
型を書きたい
Slide 91
Slide 91 text
型の恩恵を受けたい 型を書きたい
Slide 92
Slide 92 text
"書かなきゃいけないもの"にすると開発速度の低下ややらされ てる感からの生産性低下 "書く気力のある人"が少しずつ進めていくしかない。"型のあ る開発環境"を水面化で進める 機能追加のPull Requestに混ぜない。ノイズになる。型は個 別のPull Requestで余裕のある人が見る(見なくてもいい)
Slide 93
Slide 93 text
チームへの説明
Slide 94
Slide 94 text
newbieの独断では入れられない メンバーの理解と協力が不可欠 受け入れてくれたメンバーに感謝 ここまで説明したようなスタンス、メリットを伝える 「やっぱりダメだね」となった場合もすぐに剥がせる 一人でもメンテナンスしていく覚悟
Slide 95
Slide 95 text
導入の障壁 https://unsplash.com/ja/%E5%86%99%E7%9C%9F/sQ5yREHU_fI
Slide 96
Slide 96 text
gemの型不足
Slide 97
Slide 97 text
gemの型定義はまだまだ足りていない(2022年10月現在、 57個がgem_rbs_collectionにある) gemの型定義が増えるとプロジェクトに導入しやすくなるは ずだと考えています 興味がある方はぜひgemの型定義をやってみましょう!gem の型定義が増えて導入するプロジェクトが増えれば、型エコ システムの発展も早くなるかも?
Slide 98
Slide 98 text
RubyKaigi 2022 でそういう発表をしました https://speakerdeck.com/fugakkbn/types-teaches-success-what-will-we-do
Slide 99
Slide 99 text
変更への追従
Slide 100
Slide 100 text
コードの変更への追従 検知するソリューションがない メソッド追加、構造の変更など 自動で検知することができないため人力になる 別ファイルであることのデメリット 「気づいたときにやればいい」というスタンス
Slide 101
Slide 101 text
大量のエラー
Slide 102
Slide 102 text
プロジェクトに型を導入して全体で steep check を実行する と、大量にエラーが出るはず 今のプロジェクトでは1万以上のエラーが出る 繰り返しになるが、エラーを解消することに心血を注ぐ必要 はないと考えている
Slide 103
Slide 103 text
https://speakerdeck.com/soutaro/ruby-programming-with-types-in-action?slide=13
Slide 104
Slide 104 text
まとめ
Slide 105
Slide 105 text
newbieが型を書くメリットはたくさんあります!興味の裾野 を広げる一歩目にいかがですか? プロジェクトに型を導入することで得られる恩恵は限定的。 でも新しいメンバーがいち早くプロジェクトに馴染む助けに もなりそう。 小さく始められてランタイムに影響を与えないので導入しや すい。メンバーから打診があったらぜひ前向きな検討を!
Slide 106
Slide 106 text
型を通じて できることが増えた 取り組む意識が変わった 興味の幅が拡がった Rubyがもっと楽しくなった
Slide 107
Slide 107 text
波 紋 波 紋 https://unsplash.com/ja/%E5%86%99%E7%9C%9F/Tf18kgGiop4
Slide 108
Slide 108 text
No content
Slide 109
Slide 109 text
型
Slide 110
Slide 110 text
誰がメンテしてる? 型
Slide 111
Slide 111 text
誰がメンテしてる? Steepのコマンドは内部 的にどう呼ばれてる? 型
Slide 112
Slide 112 text
誰がメンテしてる? どうやってコントリ ビュートする? Steepのコマンドは内部 的にどう呼ばれてる? 型
Slide 113
Slide 113 text
誰がメンテしてる? どうやってコントリ ビュートする? Steepのコマンドは内部 的にどう呼ばれてる? 型 ASTってなに? ASTってなに?
Slide 114
Slide 114 text
見える景色が変わった 見える景色が変わった 知覚できる世界が広がった 知覚できる世界が広がった https://unsplash.com/ja/%E5%86%99%E7%9C%9F/1lfI7wkGWZ4