苦手な苦手なコードリーディングのコツ

Hey guys! まむばるです。

今日は皆さんに「コードリーディングのコツ」についてお話します。

私はもともと日本ヒューレット・パッカード・エンタープライズ株式会社のicewall開発に従事していました。

いろいろなコードを読んできましたが、やはり初心者のときは「全く分からなかった」です。

「えっ?これなに?むずすぎわからん。。。」と一日の90%ぐらい思っていた時もありました。

ただコツを掴むと徐々に理解できるようになってきます。

そのコツを今日はお伝えしていきますね。

ポイントは3つです。あと加えて、おまけも1つつけときます。

  1. 仕様&入力値と出力値わかってる?
  2. マクロ視点とミクロ視点を混同してない?
  3. 命名の規則わかってる?

おまけで知っておいてほしいことは「revisionを戻しながら、コミットコメントをヒントにする」

1. 仕様&入力値と出力値わかってる?

まず一点目です。

初心者さんや新人さんに非常に多いです。
ただなんとなく小説を読むかのように「コードリーディング」をしようとする人。

まずこんなやり方をしていては伸びるわけがありません。
大事なのは必ず前もって「仕様・入力・出力」を理解してから読み始めることです。

確かに新人さんならいきなり仕様を理解するのが難しいかもしれません。
いきなり「WebAuthn」の仕様なり、「Federation」、「OpenID」の理解が含まれたりしますからね。

でもいきなりソースコードを読むのはそれ以上に難しいです。バケモンです。
新人さんに教えるときは常に心の中で「お前は天才か?」と呟いていたのを思い出します。笑

まぁヤサシイ先輩だったので1から手順に沿って教えましたけどね。笑

仕様を理解しよう

つまり簡単に言えば「このプログラムは何してるんだろう?」です。
仕様の理解とはソースが分からなくても「口語で説明できる」レベルを指しています。

簡単な例を挙げるとすると、
かけ算をするというプログラムがあったとします。

ソースコードには以下のようなプログラムが書いてあったとします。

----------------------
入力:整数型A, B

// B回AをRETに足すループ
for(整数型i = 1, i <= B, i++) {
     RET = RET + A;
}

出力:整数型RET
----------------------

いきなりソースコードを読む人は「何をいきなり足し算を繰り返しているんだ?」という疑問から
スタートします。これはかなりきつい。時間がめちゃめちゃかかります。
いいですか。今仕事中で作業効率を意識しないといけないんですよ?
意地でも定時で帰る必要があるわけです。
残業は仕事ができないやつがすることです。(できすぎて仕事が山のように降ってくる天才だけは別!笑)

私はほぼ「オンスケ」報告です。どれだけ前倒しでも「オンスケ」でした。笑
(心の中では管理職&プロマネredmine確認せ~よ笑。と思ってました)
だから遅延することはありません。猶予がありますから。常に「オンスケ」ですからね。笑

※redmine:プロジェクト管理ツール。タスクを管理できたりするよ。(TrelloのLv.10アップみたいな笑)

なのでこんなところで時間を費やしてはいけません。

先に「あ~これはかけ算をするプログラムなんだな」というフレームワークを頭にインプットしてから読むべきです。

優秀なプログラマが作るプログラムなら大体わかりやすく書いてくれています。
JavaならJavaDocとかに書いてくれていますし、
ソースになければ詳細設計書に書いてくれていたりします。

そこから抽出するようにしましょう。
コードリーディングにかかる時間が半減します。

誰かがやさしく書いてくれているガイドラインを使わない手はありません。

2. マクロ視点とミクロ視点を混同してない?

次に2点目です。
これも新人さんによくあるパターンです。

新人Aくん「先輩。この関数意味分からないです。」

と聞かれるわけですが、めちゃめちゃ深いところで呼び出される関数を聞いてきます。

私「じゃあ呼び出し元の処理は理解できてるん?」

と聞くと

新人Aくん「あっ。そこも理解できないんですよね。」

と答えるわけです。

まず理解する順番は必ず「階層の浅いところ」から大まかに理解して、
「詳細の処理」を理解していくのがディファクト・スタンダードです。

この順番は天地がひっくり返っても不変です。

「マクロ(全体像)」な視点から「ミクロ(詳細)」な視点への推移です。

Javaならmainメソッド、他の言語でも呼び出し階層の浅いところは関数呼び出しだけで出来上がっていることが多いです。
だから関数名で中身を理解していけば全体像は容易に理解できます。

焦らずにゆっくりでいいので、全体像をつかむようにしましょう。

3. 命名の規則(慣例も含む)わかってる?

最後の3つ目のポイントです。

初心者エンジニアさんはあんまり深く考えることが少ない「命名の規則」についてです。

プログラマなら一度は「命名規則」を見たことがあると思います。
プログラムで使用される任意決定部分(変数名や関数名など)を規則として決めているドキュメントです。

具体的なものを羅列するのは避けますが、
例えば、Bool系の変数では「2値的な単語」を使うようにします。
Yes/Noが明確に判断できる動詞です。
下記のようなものが例に挙げられると思います。

  • is~
  • can~
  • exists~

このような命名規則(慣例)を理解しておくと、コードリーディングが速くなります。

Qiitaなどで調べるといろいろ出てくるので、学習してみてください。
↓Javaの例です。

おまけ:revisionを戻しながら、コミットコメントをヒントにする

大体の現場では、バージョン管理をしていると思います。
逆にしていない現場ならすぐに導入を促すか、辞めたほうが良いかもしれません。

バージョン管理をしているプログラムなら、
コミットポイントに状態を戻すことができます。
さらに、コミットの差分も簡単に見ることができます。

つまり、現状に至った歴史(History)をさかのぼることができます。
慣れてくると、世界史や日本史の授業を受けているかのような錯覚を起こします。

さらになんということでしょう。先輩が素敵な素敵な「コミットコメント」を残してくれています。
なんか素敵ですよね。過去からの伝達みたいで、「STEINS;GATE」みたいです!

これらを活用すれば、コードリーディングが速くなること間違いなしです。

さいごに

とはいっても、いきなり読むのは難しいですよね。
古典語の解読を趣味としている人は別にして、初心者プログラマにとってはやはりハードです。

しかし、楽しさを見出せるようになれば確実に読むスピードは上がります。

また、自分自身がプログラムを組み際の意識も変わってきます。
自分以外の誰かが読むのだから「キレイで読みやすい」プログラムを作成しようと思うでしょう。

そんな時におススメなのは「リーダブルコード」です。
分かりやすいプログラムとは?という観点で書かれているので、プログラマにはもってこいです。

プログラマなら一度は読んでおいて損はありません。是非チャレンジしてみてください。

今日はこのあたりで終了にさせてもらいます。

皆さんがコードを速く読めるように祈っております。

以上、現場からまむばるでした。