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 Slide

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

    View Slide

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

    View Slide

  4. View Slide

  5. ×

    View Slide

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

    View Slide

  7. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  29. newbie 心の叫び


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


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


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


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

    View Slide

  30. newbie 心の叫び


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


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


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


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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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


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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  54. 実装元を確認する

    View Slide

  55. Receive block!

    View Slide

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

    View Slide

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

    View Slide

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

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

    View Slide

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

    View Slide

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

    View Slide

  61. OSS

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  66. 型定義の誤り

    View Slide

  67. gemの型定義の不足

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  71. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  76. とはいえ…

    View Slide

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

    View Slide

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

    View Slide

  79. 小さく少しずつ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  84. CIには入れない

    View Slide

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

    View Slide

  86. 書きたい人だけ

    View Slide

  87. 型を書きたい人

    View Slide

  88. 型を書きたい人

    View Slide

  89. 型を書きたい

    View Slide

  90. 型を書きたい

    View Slide

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

    View Slide

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

    View Slide

  93. チームへの説明

    View Slide

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

    View Slide

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

    View Slide

  96. gemの型不足

    View Slide

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

    View Slide

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

    View Slide

  99. 変更への追従

    View Slide

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

    View Slide

  101. 大量のエラー

    View Slide

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

    View Slide

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

    View Slide

  104. まとめ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  108. View Slide


  109. View Slide

  110. 誰がメンテしてる?

    View Slide

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

    View Slide

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

    View Slide

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

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

    View Slide

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

    View Slide