ソースコードの読み方
ソフトウェアエンジニアにとってソースコードを読む能力はかかせません。 おそらく多くのソフトウェアエンジニアにとってプログラミングの時間の半分くらいはソースコードリーディングをしている時間でしょう。 特にソースコードのサイズが大きいソフトウェアや全体像を把握できていないソースコードを闇雲に読んでいても 時間ばかりがかかり理解できるようになるとは思えません。 例えるならばそれは英語をマスターしようとして辞典を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(これはわたし独自のショートカット)
そうすると以下の画像のようになります。
最新バージョンのファイルの各行が誰によっていつコミットされたかわかるようになります。 このmacroはSteve Purcell氏が2017-03-25 10:55にコミットしたとわかります。 このままの状態でEnterを押すとそのコミットログと差分が見れます。
このバージョンのファイルをみたいのでbを押しましょう。2
magitが親切にコマンドを教えてくれるので助かります。 checkoutしたいのでさらにbを押します。
一番上の候補にでてくるのがSteve Purcell氏が2017-03-25 10:55にコミットしたバージョンです。 自動的に該当するコミットのハッシュ値が一番上に出てくれるのでわかりやすいです。 この状態でEnterを押します。
Steve Purcell氏が2017-03-25 10:55にコミットしたバージョンのファイルを見ることができます。 これがバージョンf44ca88のファイルの実態です。
一つ前のバージョンを見たいときはこの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
最新バージョンのファイルで起動します。 一番下のミニバッファに見えるのが今見ているファイルのリビジョンです。 pを押すと一つ前のリビジョンにタイムスリップします。
pを連打して最後まで行くとバージョン1になります。 gを押した後に1を入力してもバージョン1に移動できます。
バージョン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 文脈を増やせば深く追求することができるのではないでしょうか。 何か新しいことをやるときには文脈をたくさんつくって学ぶことに気をつければ要領よくこなせるのだと思います。
ブログ記事を投稿したらTwitterでお知らせいたします。ブログを気に入っていただけた方はお気軽にフォローしてください。
— Solist Work (@SolistWork) 2018年11月27日
最新記事
タグ一覧
-
ansible (2)
application (8)
chrome (1)
command (13)
django (1)
docker (3)
document (1)
emacs (14)
git (2)
google (1)
hugo (1)
kubernetes (1)
linux (19)
makefile (6)
mariadb (2)
melpa (1)
postgresql (2)
python (1)
security (2)
terminal (11)
thinkpad (2)
work (5)
zsh (10)