はじめに
こんにちは。株式会社Relicのみけたです。
Railsのバックエンドエンジニアとして、弊社自社プロダクトの開発・保守に2年半携わっています。
おかげさまで弊社も規模が順調に拡大し、今年は新卒エンジニアがなんと11人も入社しました!
キャッチアップをしてもらい、互いに切磋琢磨をしながら会社を盛り上げていきたいと思っております。
そこでその一助になればと、「コードレビューで協力したいけれども、そもそもコード読むのむずいし、つまらないし、体質に合わない」というあなたや、「実装しなくちゃいけないから関係する周辺コードを読んだけれども何も分からないし、つらみがすごくて爆発しそう」というあなたに向けて、コードを読む上での方法論をまとめてみました。(Railsを担当するサーバーサイド向け)
何かの参考になれば幸いです。
1. コードが読めない原因を特定しよう
目に前に繰り広がるアフリカの大自然のような大量のコードを眺めていると、わたしっていうプログラマーは何ってちっぽけな存在なんだろうと黄昏れてしまうものです。
そんな黄昏れているあなたを見て先輩は「どうしたんだ、どこか詰まっているのか?」と気にかけてくれるかもしれないです。
しかし、あなたが返せるのは「いや、なんかムズくて、コード多くて、わたしってこの仕事向いてないのかもしれないなって退職届を書こうと悩んでいたところなんです」という言葉だけかもしれません。
切ないですね。ただ、退職届を書くにはまだ早いです。
分かることと、分からないこと。
それらを丁寧に分けいきましょう。
なぜなら、「分かる」ということは、その文字のごとく、ものごとを分けて整理していくということであり、それが分かることへの第一歩だからです。(ええこと言った)
このフローチャートを使えば、あなたが何が分からないのかクリアになります。
どこでつまづいたのか、どのパターンに当てはまるか確認していきましょう。
2. 処理の流れをおさらいしよう
まず、フローチャートを見ていく前に、一旦落ち着きましょう。
お茶でも飲みましょう。コーヒーが好きならコーヒーでもいいでしょう。
ヤングなあなたはエナドリでもいいでしょう。
そして落ち着いて後に、振り返っていきましょう。
「Webアプリケーションって、そもそもどうやって動いているんだっけ。」
「美味しいなにかではないことはたしかだよな」と。
難しいことやっているかもしれないですが、大体がこんな感じなはずです。
MVCの設計であることを前提にして記載します。
- エンドポイントを叩く!
- どこかのコントローラーのアクションが実行される。
- データベースに必要に応じてアクセスする。
- ゴニョゴニョ、うにうに、なんか処理をする。
- データベースに必要に応じて保存(削除)をする。
- クライアントに対して、なんか返す!
分かりましたね。要は、これですわ。
詳細に知りたい・復習したい方は、「Rails MVC」などのキーワードで検索してみてください。
3. エンドポイントを把握する
さあ、処理の流れを把握できたので、フローチャートに回答していきましょうか。
あなたが叩くエンドポイントを特定していきましょう。
エンドポイントは、ブラウザ上から簡単に特定することができます。
例えば、「お題は不問! Qiita Engineer Festa で記事投稿!」の記事のエンドポイントは https://qiita.com/official-events/4f3daca63fb78f16df0b です。
エンドポイントも分かったので、データ取得系かデータ保存系か特定していきましょうか。エンドポイントは、コントローラの特定のアクションを呼び出しているので、そのアクションをみてみましょう。
・
・
・
え、どうやるか分からないって。
困りましたね。。。
Railsの説明になってしまいますが、以下を活用して、エンドポイントとコントローラ上のアクションとの対応関係を確認することができます。
- ターミナルで「rails routes」もしくは「rake routes」コマンドを実行する
- アプリケーションを立ち上げた状態で、ブラウザ上で
ホスト名/rails/info/routes
を入力する(例: `localhost:3000/rails/info/routes)
例えば、以下のようなルーティングであるとしたら、customersというパスに対してPOSTで呼ばれている場合に、customersコントローラのcreateアクションが実行されていることが分かります。
Prefix | Verb | URI Pattern | Controller#Action |
---|---|---|---|
customers | POST | /customers(.:format) | customers#create |
また、Railsの場合、基本的には7つのアクション(index, new, create, show, edit, update, destroy)を使って設計していこうぜという思想があるので、index/new/show/edit
といったアクションが呼ばれている場合は「データ取得系」、 create/update/destroy
といったアクションが呼ばれている場合は「データ保存(削除)系」だと推測できるかと思います。
なお、HTTPメソッドの種類でも推測することができます。GETであればデータ取得系であることが多いですし、POSTやPATCHなどであればデータ保存系が多いです。
こうした知識を活用して、そもそもどういう処理がされていそうか推測していきましょう。
(まあ、UIから大体分かるケースが大半な気もしますけど、それは言わないでくれ)
4. 処理の種類を確認する
さあ、フローチャートの最初の質問に回答できました。
呼ばれているコントローラとアクションも特定できたとしましょう。
フローチャートに記載のとおり、大別すると、以下の2つのパターンに分かれていきます。
どちらのパターンに該当するか確認し、何を把握すべきなのか抑えましょう。
データ取得系
このパターンであれば、以下を把握しましょう。
HTTPメソッドであれば、GETにあたるものです。
- 何のデータを取得しているのか
- データをどう加工しているのか
データ保存(削除)系
このパターンであれば、以下を把握しましょう。
HTTPメソッドであれば、POSTなどにあたるものです。
- クライアントから何が送られてきているのか
- その送られてきたものをどう加工しているのか
- そのデータがどう保存されているのか
5. コードを読みつつ、フローチャートに答えていく
さあ、ついに本題です。
フローチャートの最初の質問に回答できたので、次の質問に回答していきましょう。
例えば、データ取得系のエンドポイントであれば、「何のデータを取得しているか」という質問が次に来ますね。分かるのであれば、それはファビュラスブリリアントなことですが、分からないのであれば、「けど、どのあたりで処理しているか 『1 分かる』 『2 分からぬ』 『3 もう読むのしんどい』」という質問が次に来ますね。
(そう、気づいたかもしれませんが「分からぬ」と回答した場合、全ての道はこの質問へと続いています。昔のヨーロッパで全ての道がローマへと続いていたのと一緒ですね。)
この質問から、以下のいずれかに最終的に分岐していきます。
- どのあたりで処理しているか分かるが、メソッドの意味が分からない場合
- メソッドの意味を調べよう
- デバッガーを活用しよう
- どのあたりで処理しているか、そもそも分からない場合
- 異常系の処理か見極め、探す範囲を狭めよう
- どのあたりで処理しているか分からないし、読むのが疲れてしまった場合
- とりま、シーシャでチルする
- ローカルで動かして、処理の流れを把握
- 読んだところまで、メモに残す
そこで、それぞれのケースについて説明していきます。「シーシャでチルする」方法と「読んだところまで、メモに残す」方法については割愛させていただきますので、ご了承ください。
メソッドの意味を調べよう
どのあたりで処理しているか分かるが、メソッドの意味が分からない場合、あなたはフローチャートに導かれ、「メソッドの意味を調べよう」という回答にたどり着いたはずです。
分からないメソッドがあれば、その言語やフレームワークが提供しているメソッドなのか、それとも実装されているメソッドなのか判別し、きちんとその意味を調べましょう。
言語やフレームワークが提供しているメソッドの場合、ドキュメントを活用してください。
Rubyであれば、こちらを参照してください。
https://docs.ruby-lang.org/ja/3.2/doc/index.html
Railsであれば、英語ですけどこちらを参照してください。
https://api.rubyonrails.org/
また、Macで開発しているのであれば、個人的にはDashというアプリがオススメです。無料だと機能に制限がありますが、複数のAPIリファレンスを横断的に検索することなんかができたりします。
https://kapeli.com/dash
https://qiita.com/imk2o/items/3f7e507c1ea857c8f225
また、無料だとDevDocsもオススメです。
ブラウザ限定のようですが、同じく横断的に検索できます。
https://devdocs.io/
デバッガーを活用しよう
どのあたりで処理しているか分かるが、メソッドの意味が分からない場合、「メソッドの意味を調べよう」という回答だけでなく、「デバッガーを活用しよう」という回答にもたどり着いたはずです。
実装されたメソッドについては、コードをまず読むことに努めてもらいたいですが、それでも理解がなかなか追いつかない場合、デバッガーを利用するのがおすすめです。
デバッガーを活用すれば、変数にどういった値が格納されているか、メソッドの返り値がどういったものになるか確認できます。脳内で追えないものについては逐一調べていくようにしましょう。
異常系の処理か見極め、探す範囲を狭めよう
どのあたりで処理しているか分からない場合、あなたはフローチャートに導かれ、「異常系の処理か見極め、探す範囲を狭めよう」という回答にたどり着いたはずです。
既に記載のとおりですが、コードというのはアフリカの大自然のように広がっています。「気合で読むんだ、気合で!! バッキャロウ!!」という根性論の先輩にドヤされるかもしれませんが、読む範囲は極力狭くできるといいですよね。
その回答の一つとなるのが、「異常系の処理か見極める」です。コードの中には結構な割合で「想定外は弾くぜ系コード」がありますが、そういう類のコードか見極めて無視していきましょう。
例えば、名前を入力しろやってフォームがあるのに、平気な顔して名前の記入欄を未記入で送信する不届き者が世の中には蔓延っていますが、それを弾いて、「氏名が未記入です」とエラーメッセージを返すためのコードが「想定外は弾くぜ系コード」の典型例です。
「想定外は弾くぜ系コード」は非常に重要なのですが、ふんわりとコードの流れをつかむ上では邪魔になることが多いです。「あああああああああ!!! もうコードをこれ以上読むと爆発する!!!!」という状態なのであれば、正常に処理がされるパターンのコードのみを読むことに全集中しましょう。
ローカルで動かして、処理の流れを把握
どのあたりで処理しているかという質問に対して、「もう読むのしんどい」という投げやりな回答をした場合、あなたはフローチャートに導かれ、「ローカルで動かして、処理の流れを把握」などと書かれた回答にたどり着いたはずです。
まずは、シーシャでチルしてもらうべきなのですが、それが済んだと仮定しましょう。
実装を理解する上で、まず大雑把なイメージを掴むのが大事です。アプリケーションを立ち上げて触ってみて、ビジュから理解を深めていきましょう。
人を叩くのはよくないですが、エンドポイントを叩くのは合法です。気が済むまで叩きましょう。
エンドポイントを叩こうにも、その画面に行き着くには色々な条件があって、その労力がめちゃくちゃしんどいというのはあるあるです・・・ その場合、関連コードを読んでいけばその条件も大概分かるのですが、それができなくて困っているので、素直にプロジェクト歴が長い先輩に質問しましょう
エンドポイントを叩くと、以下のような現象が把握できるかと思います。
- 〇〇ページが表示される
- 〇〇一覧ページに遷移して、フラッシュメッセージに〇〇が保存されましたと表示される
この程度の理解で大丈夫なので、ざっくりと把握しましょう。
このざっくり理解がまず大事です。
「これはデータベースから取得して表示してる情報やろうな」
「データベースから表示するにしても加工してあげへんとこの表示にならならへんな」
と妄想を膨らませることまでできたらベストです。
夢と希望と妄想を膨らませれば、予想しながらコードを読むことが出来ます。ここまで出来たタイミングで一旦コードに戻ってみましょう。
6. フローチャートで解決しない場合は質問しよう
フローチャートを活用して、一定の対応方針が示されたのではないでしょうか。
・メソッドの意味を調べて意味が特定できた人
・異常系の処理を見極められ、自分が把握すべき処理がどこに書かれているか特定できた人
・読むのがしんどかったがイメージが湧いて、コードに再度立ち向かえた人
こうした方々は素晴らしいですね。
引き続き、コードと対峙し、理解へと邁進してもらえればと思います。
他方で、それでも分からず、脳みそが溶けておかしくなりそうな方も一定数いるかと思います。
会社としては、あなたの脳みそは溶けても知ったこっちゃないですが(いや、よくないよ!)、時間が溶けていってしまうのは困ってしまいます。自身にも周りにもよくないので、そういった場合は先輩に質問しましょう。
ここでも、フローチャートが役立っているはずです。
というのも、「もう何がなんだか、わかめなんです!!!」という曖昧な形ではなく、以下のように、一定程度の具体的な形で質問ができるはずだからです。
・〇〇というメソッドが分からず、公式ドキュメントを使って調べましたがよく分かりませんでした。
・データ取得系のエンドポイントなのでデータ取得の処理がどこかにあるはずなのですが、どこか特定できませんでした。
・ローカルで動かそうと思ったのですが、エンドポイントの画面にたどりつけず、「権限がありません」と表示されます。どこで権限制御がされているのでしょう。
ただ、質問する際には、よりブラッシュアップできるとよいです。
質問する際には、以下などを参考にしてください。
例えば、こんな感じです。
(1) 実現したいこと
・ 送信されるパラメータをデバッガーで調べたいが、どうすればいいか分からない
(2) 実現するために自分が試した内容とその結果
・ コントローラのアクション内でデバッガーを仕込んでみた
・ しかし、どの変数(もしくは他のもの?)を確認すればいいのかよくわからない
(3) 調べた内容や資料
・ 「Rails パラメータ」で検索してみました
・ 〇〇という記事は読みましたが、よくわかりませんでした(リンクも付ける)
(4) 原因だと思われそうな箇所
・ User.new
の引数にuser_params
とあるのでそれが怪しい気がしました
このようなフォーマットに沿えるといいですね。
いいですね通り越して、もはやFですね。
なお、質問する際には、答えを聞くだけでなく、先輩がなぜ答えに到達できたのかといった点まで意識しましょう。そこまでできると、自立できるのも早くなるでしょう。
7. 最後に激励!
コードを読むのって正直しんどいですよね。こんな晴れた夏空にもかかわらず、他人が書いたコードを好き好んで読まなくちゃいけないのはおかしいですよね。
私も、陰キャなインドア派であるにもかかわらず、湘南乃風でも聴きながら江ノ電に乗りたい気分になります。
ただ、エンジニアというのは、地道なお仕事です。経験があるエンジニアであっても、見慣れないサービスの見慣れないコードを読むのには時間がかかるものです。
読む範囲は絞りつつも、以下の原則は忘れないようにしましょう。
ちゃんと1行ずつ、コードを読みましょう。
Repeat, after me. ちゃんと1行ずつ、コードを読みましょう。
これだけ書いといてなんですが、最後は気合じゃ!!!
気合を入れて、時間をかけて読めば、最後はどうにかなる!
参考になりそうなQiita記事