Solist Work Blog

Software engineer note

ソースコードの読み方

ソフトウェアエンジニアにとってソースコードを読む能力はかかせません。 おそらく多くのソフトウェアエンジニアにとってプログラミングの時間の半分くらいはソースコードリーディングをしている時間でしょう。 特にソースコードのサイズが大きいソフトウェアや全体像を把握できていないソースコードを闇雲に読んでいても 時間ばかりがかかり理解できるようになるとは思えません。 例えるならばそれは英語をマスターしようとして辞典を1ページから読んでいくようなものです。 私は学生時代に辞書を読もうと試みたもののあまり成果はでませんでした。 今になって考えると文脈や脈絡のないものを読んでそれをマスターすることは人間とって無理難題であると思います。 ソースコードも辞典と同じく読みにくいものですから、読むためには文脈が大切であるのだとわかります。

ソースコードを読むための文脈

ソースコードを読むために利用できる文脈は3つあると思います。 1つ目の文脈はエントリーポイントから動いている順番に読んでいく実行の文脈です。 2つ目の文脈は興味の文脈です。ソフトウェアエンジニアが何かを作っていて同じようなことを実現しているソフトウェアの実装部分を見るときとか、 これはどういう仕組みで動いているのか気になってその部分だけのソースコードを読むときの文脈です。 3つ目の文脈は歴史的経緯という文脈です。現在のソースコードを見ただけではわからないが歴史をたどっていくとなぜこのように書かれているのか理解できるようになるという文脈でしょうか。

全体像を把握したあとであるならば一行目から読んでも問題ないでしょうが、全体像を把握するまではなんらかの文脈で読んでいかないとうまくいかないでしょう。 辞書を1ページから読んでも問題ないのは辞書を作っている人間かその分野の専門家であるのと同じことだと思います。 1つ目の実行の文脈は当たり前のように思うのでこれ以上とくに書くことはありません。 2つ目の興味の文脈はまず何かに興味を持たないといけないでしょう。 誰かのブログを読んで面白そうといって真似してもたいして実力がつかないのはそれほど興味がないからだと思います。 それはある種の人からもらった興味であって自分から湧き出た興味ではないからかもしれません。 一人でプログラミングしていてどうしても作りたいものがあったときに、 似たような機能を実現しているオープンソースを見つけてそのソースコードを読んで参考にするのとはわけがちがうと思うからです。 自分から湧き出た興味を持ち続けるためには新しい発想で新しいプログラミングに挑戦しつづけないと興味は枯渇していくのだと感じています。そうならないように努力していかなければいけません。

歴史的経緯を読むためのGit関連ツール

さて、3つ目の歴史的経緯の文脈を把握するためにどうやっているか書いていきたいと思います。

調べたい関数にポインタを置いている画面

画像にあるeasy-hugo-with-envというmacroの歴史を調べることにします。 この行でmagit-blameを立ち上げます。1

M-x magit-blame or C-x G(これはわたし独自のショートカット)

そうすると以下の画像のようになります。

magit-blameが起動した画面

最新バージョンのファイルの各行が誰によっていつコミットされたかわかるようになります。 このmacroはSteve Purcell氏が2017-03-25 10:55にコミットしたとわかります。 このままの状態でEnterを押すとそのコミットログと差分が見れます。

magitで差分を見ている画面

このバージョンのファイルをみたいのでbを押しましょう。2

magitがコマンドを教えてくれる画面

magitが親切にコマンドを教えてくれるので助かります。 checkoutしたいのでさらにbを押します。

magitでgit checkoutしている画面

一番上の候補にでてくるのがSteve Purcell氏が2017-03-25 10:55にコミットしたバージョンです。 自動的に該当するコミットのハッシュ値が一番上に出てくれるのでわかりやすいです。 この状態でEnterを押します。

指定したリビジョンに移動した画面

Steve Purcell氏が2017-03-25 10:55にコミットしたバージョンのファイルを見ることができます。 これがバージョンf44ca88のファイルの実態です。

magit-blameの画面

一つ前のバージョンを見たいときはこのmagit-blameの画面でbを押すと Steve Purcell氏が2017-03-25 10:55にコミットしたバージョンの一つ前のコミットがみれます。 magit-blameの画面でcを押すと表示を切り替えて見やすくできます。 cを押すたびにトグルでmagit-blame表示が変わっていくので便利です。 qでmagit-blameは終了します。

git-timemachineで履歴を遡る

歴史をたどるときは各バージョンのGitの差分だけみるよりもバージョン間を簡単に移動できればもっとわかりやすくなります。

1 -> 2 -> 3 -> 4 -> 5

まだ全体像を把握していないときにバージョン1と2の差分を見て、バージョン2と3の差分を見てもよくわからないことが多いです。 こういうときはバージョン1のファイルを見てからバージョン2のファイルを見たほうがわかりやすいことがあります。 git-timemachineを使うとタイムマシンのように各バージョンを移動できるようになります。 MELPAからインストールするだけで使えるようになります。

M-x package-install git-timemachine

インストールしたあとに以下のコマンドをたたきます。

M-x git-timemachine

git-timemachineが起動したところ

最新バージョンのファイルで起動します。 一番下のミニバッファに見えるのが今見ているファイルのリビジョンです。 pを押すと一つ前のリビジョンにタイムスリップします。

git-timemachineでバージョン1に移動したところ

pを連打して最後まで行くとバージョン1になります。 gを押した後に1を入力してもバージョン1に移動できます。

git-timemachineでバージョン2に移動したところ

バージョン1にいるときに n を押すとバージョン2になります。 gを押した後に2を入力してもバージョン2に移動できます。

コミットメッセージで移動するところ

tを押すとコミットメッセージ一覧を選択できるようになるので選ぶと そのコミットメッセージのリビジョンに移動できます。 コミットメッセージをわかりやすく書いておくことの重要性がわかります。

git-timemachineがなぜよいのかというと大きなソースコードを読むときに便利だからです。 OSの違いを吸収するささいな木の枝のようなソースコードを読むことは重要ではありません。 重要なのはこのソフトウェアの木の幹のようなコアな実装です。 木の幹だけ読んでいけば全体像を把握しやすくなるのです。 枝の部分はMaintainerでも無い限り読む必要に迫られることはないでしょう。 そしてどんなソフトウェアも幹から作っていきます。 そのうちに使うユーザーが増えて要望やプルリクエストが来て枝が増えていきます。 git-timemachineを使ってバージョン1から順番に読んでいくと幹の部分が把握しやすくなります。 初期バージョンはたいていの場合シンプルであるのでソースコードリーディングにはうってつけなのです。3 まず全体像を把握しなければ話は始まりません。 いきなり木の枝の部分を読むということは辞典を1ページから読むようなものなのでやめましょう。 ソースコードリーディングするときは文脈が大事なのです。

git-timemachineのコマンド

p 前のリビジョンに移動
n 次のリビジョンに移動
w 現在見ているリビジョンのハッシュをコピーする
W 現在見ているリビジョンのフルハッシュをコピーする
g 指定したリビジョンに移動
t 選択したコミットメッセージによるリビジョンへの移動
q git-timemachineを終了する
b 現在訪問しているリビジョンでmagit-blameを実行します。

文脈を大切にしよう

コンピュータ・サイエンスの本にのっている順番で読むと理論体系の文脈で学ぶことができます。 理論体系は発見された順番ではないので歴史的経緯の順番を調べて読むと歴史的経緯の文脈で学ぶこともできます。 自分の好きな人物中心にコンピュータ・サイエンスを学ぶこともできます。たとえば、ドナルド・クヌースが好きなら彼に関連のある内容を学ぶなどすれば、人物の文脈で学ぶことができます。4 文脈を増やせば深く追求することができるのではないでしょうか。 何か新しいことをやるときには文脈をたくさんつくって学ぶことに気をつければ要領よくこなせるのだと思います。


  1. magit-blameを使用するにはmagitのインストールが必要です。 ↩︎

  2. bはブランチに関するショートカットですがこれを忘れた場合は?を押せばショートカットを確認できます。 ↩︎

  3. 初期バージョンがシンプルでないということは一度のコミットで大量にソースコードをコミットするようなGitの使い方をするソフトウェアエンジニアです。そのようなGitの使い方をするソフトウェアエンジニアがよいものを書くとはとうてい思えないので読むのをやめたほうがよいかもしれません。 ↩︎

  4. ドナルド・クヌースThe Art of Computer Programmingは膨大すぎるので茨の道だと思いますが… ↩︎

タグ一覧

お仕事のご相談などはこちらからどうぞ

お仕事の依頼はこちらからどうぞ