愛と勇気と缶ビール

ふしぎとぼくらはなにをしたらよいか

僕のなんとなく思う実践的コードリーディング

コードリーディング、というのは他人のコードを読むことだが、一般的にはよいこととされている。なんとすれば、他人のコードを読むことによって自分のそれとは異なる考え方を学ぶことが出来るからである。

が、純粋な勉強目的のコードリーディングというのは(普通の人にとっては)あまり長続きしないものである。コードを読むこと自体が目的になっていて、「全てを理解する」のが最終地点になってしまっているからだ。コードが膨大であればあるほど余さず理解するのには時間がかかりすぎるし、得てして「よし!◯◯のコードをとりあえず読もう!」というモチベーションによって読まれる◯◯のコードは膨大かつ壮大である。漠然としたモチベーションの対象は、常に他者の視線を身にまとっているから。

まあそんなわけで、意味のあるコードリーディングとは

  • そのコードを読んで「何を理解したいか」「何に活かしたいか」が明確である
  • = 比較的はっきりした最終地点がある

というもんだと僕は思っている。ただダラダラ読んだってしょうがないのだ。

それに加えて、アプリケーションレイヤ(?)のエンジニアにとって価値があるのはミドルウェアのコードリーディングである。いわゆるLLなどでアプリケーションを書いている場合は、下層にあるミドルウェアをブラックボックスとして扱うことがおおい。もちろん全てのミドルウェアの中味を見ていくわけにもいかないのでこれ自体が悪いわけではないが、実際問題「このミドルウェアはこの時こういう挙動をするらしい」「ドキュメントを読んでも分からないけど実はこういう挙動がある」みたいなことを外側からあれこれ推測するよりいっそ読んでしまった方が早い、ということはままある。

敢えてブラックボックスとして取り扱うか、ソースを見てしまうか、どちらがいいかは時間的制約および対象となるコード自体のリーダビリティに依存する。

例えば比較的有名どころのミドルウェア(国勢調査による)については僕は以下の様な感想を抱いている。

  • mysql => 読めない。あるいは読めたとしても読みづらいだろうコード
  • memcached => 頑張れば普通に読める
  • redis => とても読みやすい

こうしたミドルウェアのコードを読む際に、最初に挙げた点に加えて僕がこころがけているのは以下のことである。

  • 細かいことにこだわらない
    • 全て細かいところまで追っていったらキリがなく、読むこと自体が目的になってしまう。
  • ノイズは無視する。本筋の処理を把握して、それだけを追いかける。
    • 例えばTCPサーバなら、socket -> bind -> listen -> acceptの一連の流れを追う
    • リクエストを受けてからレスポンスを返すまでが遠足です
    • それに限らずsystem callに注目して追う (あるいは、その言語におけるsystem callのラッパー関数のコールを追う)

この辺を守っていれば、例えばコードがC++で書いてあって、C++の細かい部分に詳しくなくても(僕がそうだが)何が行われているか把握するのは難しくない。おおむねの文法さえ分かっていれば、どの言語で書いてあろうと別に恐れる必要はない。全てを理解することが目的ではないのだから。

そんなわけで、別に読むこと自体に意味があるわけじゃないけど、まあ同じ人間が書いたものだし、この世に魔法があるわけじゃなし、「実際どうなるんだろう?」という疑問がわいたらとりあえず何でもソースコードを読んでみることをオススメするのだ。

はじめてのOSコードリーディング ~UNIX V6で学ぶカーネルのしくみ (Software Design plus)

はじめてのOSコードリーディング ~UNIX V6で学ぶカーネルのしくみ (Software Design plus)