Upgrade to Pro — share decks privately, control downloads, hide ads and more …

入社数ヶ月のnewbieが 稼働7年超のプロジェクトに 型を導入して見えた世界

Fu-ga
October 22, 2022

入社数ヶ月のnewbieが 稼働7年超のプロジェクトに 型を導入して見えた世界

Kaigi on Rails 2022 登壇資料

Fu-ga

October 22, 2022
Tweet

More Decks by Fu-ga

Other Decks in Programming

Transcript

  1. Kaigi on Rails 2022 - 10.22(Sat)
    入社数ヶ月のnewbieが
    稼働7年超のプロジェクトに
    型を導入して見えた世界
    ふーが@fugakkbn / ESM, Inc

    View full-size slide

  2. Profile
    ふーが @fugakkbn
      2022年3月からエンジニアに(at ESM, Inc)
      Railsを使用したアプリケーション開発
      gem_rbs_collectionのコントリビューター
      プロジェクトへの型導入を進めている
      Kaigi on Rails Organizer

    View full-size slide

  3. 動機
    なぜ型に興味を持ったのか?
    初めての型
    TypeScriptで静的型に初
    めて触れ、型があること
    のメリットを知った。
    Rubyでも型の恩恵を
    3.0からRubyでも静的型
    を扱えるようになった
    が、プロジェクトには導
    入されていなかった。
    後押し
    1on1でEMに「型に興味
    がある」話をしたら「プ
    ロジェクトに導入してみ
    たら?」

    View full-size slide

  4. コミュニティとの
    ”共生”
    このワードにピンと来た方は…
    @fugakkbn or agile.esm.co.jp まで!!

    View full-size slide

  5. Kaigi on Rails 2022 - 10.22(Sat)
    入社数ヶ月のnewbieが
    稼働7年超のプロジェクトに
    型を導入して見えた世界
    ふーが@fugakkbn / ESM, Inc

    View full-size slide

  6. アジェンダ
    newbieこそ型定義をするべき
    どのように導入を提案したか
    導入する上での障壁

    View full-size slide

  7. 今日伝えたいこと
    newbie の皆さん
    型情報から得られるフィードバック以外にもたくさんのメ
    リットがあることを知って欲しい
    もし型に興味を持ってもらえたなら、ぜひプロジェクトへ
    の導入を!
    先輩の皆さん
    同僚から型導入の打診があった時は今日紹介するようなメ
    リットを思い出して、ぜひ導入の支援をお願いします!

    View full-size slide

  8. RBSの文法、書き方
    導入の具体的な手順

    View full-size slide

  9. 用語の紹介
    基本的なものだけ紹介
    RBS
    Rubyの型を書くための言
    語の名称。Ruby Likeな
    書き方ができるため理解
    やすい。
    Steep
    Rubyの静的型解析機。
    steep checkコマンドで
    Rubyファイルとrbsファ
    イルの型検査ができる。
    ジェネレーター
    この発表では「プロダク
    トコードをもとにRBSの
    コードを自動生成するも
    の」として話します。

    View full-size slide

  10. newbieこそ型定義をするべき
    https://unsplash.com/ja/%E5%86%99%E7%9C%9F/ak4hw4r6xio

    View full-size slide

  11. なぜ?
    理由はいくつかあります
      コードを読み解きやすくなる
      プロジェクトの全容把握の近道になる
      実装を読むことへの抵抗がなくなる
      無限にコントリビュートチャンスがある

    View full-size slide

  12. なぜ?
    理由はいくつかあります
      コードを読み解きやすくなる
      プロジェクトの全容把握の近道になる
      実装を読むことへの抵抗がなくなる
      無限にコントリビュートチャンスがある

    View full-size slide

  13. 皆さんに質問 プロジェクトに全部でいく
    つのメソッドが定義されて
    いますか?
    また、それらの引数にはど
    んな値が入りますか?

    View full-size slide

  14. とあるアプリのメソッド数

    View full-size slide

  15. とあるアプリのメソッド数

    View full-size slide

  16. すべてを覚えておくのはムリ!
    一度読んで理解してもしばらくしたら忘れてしまう
    先輩のコードをレビューしているとき、テストコードを読み解くとき、障害発生
    時に調査するとき…などなど、折に触れてメソッドの構造を理解するべきタイミ
    ングがあると思います。

    View full-size slide

  17. そこで型ですよ
    型があれば覚えておく必要がない
    なぜなら型を見ればどんな引数を渡してどんな返り値なのかが一目でわかるから
    「これってどういうメソッドなんだっけ?」から始まる調査の手間は決して軽い
    ものではないはず。

    View full-size slide

  18. rbsファイル
    アプリケーションコード

    View full-size slide

  19. rbsファイル
    アプリケーションコード

    View full-size slide

  20. rbsファイル
    違う型を引数に渡そうとすると…

    View full-size slide

  21. rbsファイル
    型が違うことを教えてくれる!

    View full-size slide

  22. 型をつけたことで
    たくさんあるメソッドを
    読み解きやすくなった

    View full-size slide

  23. 型をつけたことで
    たくさんあるメソッドを
    読み解きやすくなった

    View full-size slide

  24. なぜ?
    理由はいくつかあります
      コードを読み解きやすくなる
      プロジェクトの全容把握の近道になる
      実装を読むことへの抵抗がなくなる
      無限にコントリビュートチャンスがある

    View full-size slide

  25. プロジェクトの
    全容把握
    newbieな僕の最初の壁 その1

    View full-size slide

  26. newbie 心の叫び


    どこに何が定義され
    ているのかわからな
    い。モデル同士の関
    連どうなってるの?


    「簡単な修正」って
    issue 振ってもらっ
    たけど…どこから手
    をつければいいの?


    メソッドの処理が複
    雑すぎて最終的にど
    うなるのかわから
    ん!!!


    コードジャンプ候補
    に同名メソッドがた
    くさん出てきてどれ
    が正しいのかわから
    ない。。。

    View full-size slide

  27. newbie 心の叫び


    どこに何が定義され
    ているのかわからな
    い。モデル同士の関
    連どうなってるの?


    「簡単な修正」って
    issue 振ってもらっ
    たけど…どこから手
    をつければいいの?


    メソッドの処理が複
    雑すぎて最終的にど
    うなるのかわから
    ん!!!


    コードジャンプ候補
    に同名メソッドがた
    くさん出てきてどれ
    が正しいのかわから
    ない。。。

    View full-size slide

  28. そこで型ですよ
    型を書くことで理解が深まる
    型を書くにはメソッドの使い方や使用時の挙動を調査する必要がある。
    それを繰り返す中でどんどんわかることが増えていき、プロジェクトへの理解が
    深まっていく。

    View full-size slide

  29. 型定義を進めるために嫌でもプロジェクト内のファイルを横
    断的に見ることになる
    モデル同士の関連がどうなっているか理解が進んだり、この
    モデルにこんなメソッドがあるのか!などの発見がある
    それらに型付けする過程でユースケースやどこで使われてい
    るのかなどが自然とわかる

    View full-size slide

  30. 別のメリット
    今後の自分の助けにもなる
    型付けが進むとIDEの補完の正確度が上がる。正確度が上がると調査
    も実装も速度が上がるため、相対的に同じ時間内で得られる情報量
    が増える。

    View full-size slide

  31. 補完候補(型がない場合)

    View full-size slide

  32. 補完候補(型がない場合)

    View full-size slide

  33. 補完候補(型がある場合)

    View full-size slide

  34. 補完候補(型がある場合)

    View full-size slide

  35. nextメソッドの定義を見たい!

    View full-size slide

  36. ここでコードジャンプしようとすると…

    View full-size slide

  37. 候補がたくさん表示されてしまう

    View full-size slide

  38. 型をStringだと定義しておくと…

    View full-size slide

  39. 一発で String#next の定義元に飛べる!

    View full-size slide

  40. 型をつけたことで
    プロジェクトへの理解が進み
    調査や実装もしやすくなった

    View full-size slide

  41. 型をつけたことで
    プロジェクトへの理解が進み
    調査や実装もしやすくなった

    View full-size slide

  42. なぜ?
    理由はいくつかあります
      コードを読み解きやすくなる
      プロジェクトの全容把握の近道になる
      実装を読むことへの抵抗がなくなる
      無限にコントリビュートチャンスがある

    View full-size slide

  43. gemの実装を見るのが苦手
    newbieな僕の最初の壁 その2

    View full-size slide

  44. 苦手な理由
    思い返してみると…
    難しいコードがたくさん出てくる印象
    どこから見ればいいのかわからない
    「まだ自分には読めない」という先入観

    View full-size slide

  45. 型生成プロセス
    良いサイクルが生まれます
    調査
    メソッドの構造
    (引数の型、返
    り値の型)や使
    われ方を調査す
    る。
    型定義
    調査結果をもと
    に型を定義して
    いく。このとき
    gem の型定義
    の不足や誤りが
    判明することも
    実装の確認
    起こっているエ
    ラーが型定義の
    誤りなのかそう
    でないのかは、
    gem の実装を
    見る必要がある
    反復
    型定義はこれら
    の繰り返し。繰
    り返しやってい
    るうちに実装を
    見るのが日常に
    なる。
    成果物


    プロジェクトの
    型定義はもちろ
    ん、場合によっ
    ては OSS にコ
    ントリビュート
    できることも。

    View full-size slide

  46. steep checkで出たエラーに疑義がある場合
    gemの型定義がなくて追加しようとするとき

    View full-size slide

  47. steep check 実行時に見つかる

    View full-size slide

  48. steep check 実行時に見つかる

    View full-size slide

  49. steep check 実行時に見つかる

    View full-size slide

  50. steep check 実行時に見つかる

    View full-size slide

  51. 実装元を確認する

    View full-size slide

  52. Receive block!

    View full-size slide

  53. gemの実装を見ることが
    "日常"になった。
    あの頃の苦手意識はもうない

    View full-size slide

  54. gemの実装を見ることが
    "日常"になった。
    あの頃の苦手意識はもうない

    View full-size slide

  55. gemの実装を見ることが
    "日常"になった。
    あの頃の苦手意識はもうない

    ※ただし読めるとは言っていない

    View full-size slide

  56. なぜ?
    理由はいくつかあります
      コードを読み解きやすくなる
      プロジェクトの全容把握の近道になる
      実装を読むことへの抵抗がなくなる
      無限にコントリビュートチャンスがある

    View full-size slide

  57. OSSって
    なにから始めればいいの?
    newbieな僕の最初の壁 その3

    View full-size slide

  58. OSS
    選ばれし人がやること
    初心者の自分にできるわけがない。技術に秀でたすごい人
    たちがやること。

    View full-size slide

  59. OSS
    選ばれし人がやること
    初心者の自分にできるわけがない。技術に秀でたすごい人
    たちがやること。
    自分にできることがあるはずない
    すごい技術を持った人たちが作ったものに自分が修正でき
    るところがあるわけない。

    View full-size slide

  60. OSS
    選ばれし人がやること
    初心者の自分にできるわけがない。技術に秀でたすごい人
    たちがやること。
    自分にできることがあるはずない
    すごい技術を持った人たちが作ったものに自分が修正でき
    るところがあるわけない。
    やってみたい気持ちはあるけれど…
    どこから手をつけたらいいのか、どこが修正すべきところ
    なのか、どうやってパッチを送ればいいのかナニモワカラ
    ナイ。

    View full-size slide

  61. 型定義を始めるまでは…

    View full-size slide

  62. 型定義の誤り

    View full-size slide

  63. gemの型定義の不足

    View full-size slide

  64. 試行錯誤の中での気づき
    プロジェクトの型導入をしている中で
    gemの型定義が足りなかったり間違ってることがあるなぁ

    View full-size slide

  65. 試行錯誤の中での気づき
    プロジェクトの型導入をしている中で
    gemの型定義が足りなかったり間違ってることがあるなぁ
    これってもしや…コントリビュートチャンスってやつ!?

    View full-size slide

  66. OSSへの初めてのコントリビュート

    View full-size slide

  67. コントリビュートは
    すごい人だから
    するものではない。
    「使ってる人が
    気付いた時にするもの」

    View full-size slide

  68. コントリビュートは
    すごい人だから
    するものではない。
    「使ってる人が
    気付いた時にするもの」

    View full-size slide

  69. なぜ?
    理由はいくつかあります
      コードを読み解きやすくなる
      プロジェクトの全容把握の近道になる
      実装を読むことへの抵抗がなくなる
      無限にコントリビュートチャンスがある

    View full-size slide

  70. 興味を持ってもらえたら
    プロジェクトに型を
    導入してみてください!
    newbieの多くの悩みを解決してくれます

    View full-size slide

  71. とはいえ…

    View full-size slide

  72. newbieに型を導入する
    裁量なんてないんですが!?

    View full-size slide

  73. どのように
    型導入を提案したか
    https://unsplash.com/ja/%E5%86%99%E7%9C%9F/5Q07sS54D0Q

    View full-size slide

  74. 小さく少しずつ

    View full-size slide

  75. 第1ステップとして、rbs, rbs-rails, gem_rbs_collection
    などで大枠の型定義をそろえる

    View full-size slide

  76. 第1ステップとして、rbs, rbs-rails, gem_rbs_collection
    などで大枠の型定義をそろえる
    第2ステップとして、生成された rbs ファイルの untyped を
    正しい型に書き換えていく

    View full-size slide

  77. 第1ステップとして、rbs, rbs-rails, gem_rbs_collection
    などで大枠の型定義をそろえる
    第2ステップとして、生成された rbs ファイルの untyped を
    正しい型に書き換えていく
    並行して、steep check でのエラーから gem の型定義不足
    や誤りを見つけて修正する

    View full-size slide

  78. gemもrbsも独立しているので剥がすのは簡単
    主要なModelやAPIだけでもよい
    型があってもなくてもプロダクトコードに影響はない
    Linterで警告が出たりノイズが発生することもない

    View full-size slide

  79. CIには入れない

    View full-size slide

  80. エラーの解消が目的ではない
    目的はあくまで"開発者体験の向上"
    CIに組み込むと間違いなくエラーが出続ける
    CIがずっとredだと"オオカミ少年"状態になる…
    型のエラーを検知したい訳ではない
    プロジェクト内の型を充実させることに集中する方が建設的

    View full-size slide

  81. 書きたい人だけ

    View full-size slide

  82. 型を書きたい人

    View full-size slide

  83. 型を書きたい人

    View full-size slide

  84. 型を書きたい

    View full-size slide

  85. 型を書きたい

    View full-size slide

  86. 型の恩恵を受けたい
    型を書きたい

    View full-size slide

  87. "書かなきゃいけないもの"にすると開発速度の低下ややらされ
    てる感からの生産性低下
    "書く気力のある人"が少しずつ進めていくしかない。"型のあ
    る開発環境"を水面化で進める
    機能追加のPull Requestに混ぜない。ノイズになる。型は個
    別のPull Requestで余裕のある人が見る(見なくてもいい)

    View full-size slide

  88. チームへの説明

    View full-size slide

  89. newbieの独断では入れられない
    メンバーの理解と協力が不可欠
    受け入れてくれたメンバーに感謝
    ここまで説明したようなスタンス、メリットを伝える
    「やっぱりダメだね」となった場合もすぐに剥がせる
    一人でもメンテナンスしていく覚悟

    View full-size slide

  90. 導入の障壁
    https://unsplash.com/ja/%E5%86%99%E7%9C%9F/sQ5yREHU_fI

    View full-size slide

  91. gemの型不足

    View full-size slide

  92. gemの型定義はまだまだ足りていない(2022年10月現在、
    57個がgem_rbs_collectionにある)
    gemの型定義が増えるとプロジェクトに導入しやすくなるは
    ずだと考えています
    興味がある方はぜひgemの型定義をやってみましょう!gem
    の型定義が増えて導入するプロジェクトが増えれば、型エコ
    システムの発展も早くなるかも?

    View full-size slide

  93. RubyKaigi 2022 でそういう発表をしました
    https://speakerdeck.com/fugakkbn/types-teaches-success-what-will-we-do

    View full-size slide

  94. 変更への追従

    View full-size slide

  95. コードの変更への追従
    検知するソリューションがない
    メソッド追加、構造の変更など
    自動で検知することができないため人力になる
    別ファイルであることのデメリット
    「気づいたときにやればいい」というスタンス

    View full-size slide

  96. 大量のエラー

    View full-size slide

  97. プロジェクトに型を導入して全体で steep check を実行する
    と、大量にエラーが出るはず
    今のプロジェクトでは1万以上のエラーが出る
    繰り返しになるが、エラーを解消することに心血を注ぐ必要
    はないと考えている

    View full-size slide

  98. https://speakerdeck.com/soutaro/ruby-programming-with-types-in-action?slide=13

    View full-size slide

  99. newbieが型を書くメリットはたくさんあります!興味の裾野
    を広げる一歩目にいかがですか?
    プロジェクトに型を導入することで得られる恩恵は限定的。
    でも新しいメンバーがいち早くプロジェクトに馴染む助けに
    もなりそう。
    小さく始められてランタイムに影響を与えないので導入しや
    すい。メンバーから打診があったらぜひ前向きな検討を!

    View full-size slide

  100. 型を通じて
    できることが増えた
    取り組む意識が変わった
    興味の幅が拡がった
    Rubyがもっと楽しくなった

    View full-size slide

  101. 波 紋
    波 紋
    https://unsplash.com/ja/%E5%86%99%E7%9C%9F/Tf18kgGiop4

    View full-size slide

  102. 誰がメンテしてる?

    View full-size slide

  103. 誰がメンテしてる?
    Steepのコマンドは内部
    的にどう呼ばれてる?

    View full-size slide

  104. 誰がメンテしてる?
    どうやってコントリ
    ビュートする?
    Steepのコマンドは内部
    的にどう呼ばれてる?

    View full-size slide

  105. 誰がメンテしてる?
    どうやってコントリ
    ビュートする?
    Steepのコマンドは内部
    的にどう呼ばれてる?

    ASTってなに?
    ASTってなに?

    View full-size slide

  106. 見える景色が変わった
    見える景色が変わった
    知覚できる世界が広がった
    知覚できる世界が広がった
    https://unsplash.com/ja/%E5%86%99%E7%9C%9F/1lfI7wkGWZ4

    View full-size slide