これは Livesense Advent Calendar 2022 DAY 11 の記事です。
はじめに
最近、読み方を工夫することで長い間積読になっていた技術書を読了しました。相性が合う本および読者であればこの読み方はお薦めできると思ったので紹介します。
具体的には、GitHubを利用してこういうふうにして読んでいます。
- Pull Requestの差分を利用して実装をわかりやすくする
- Pull Requestのコメントを利用してメモを取る
- Pull Requestを利用して本のページをコードと共に残す
- Pull Requestのラベルを利用して節ごとにわかりやすく一覧化する
やりたかったこと
『Go言語でつくるインタプリタ』という本があります。 わたしはこの本が日本で出版された翌年(今から4年前)に読みはじめましたが、途中で挫折して読み切ることができませんでした。具体的には、「構文解析」の章でつまづきました。
本書の構文解析の章は他の章に比べてボリュームがあり、ところどころ解説に対するコードが省略されている部分があるので、道に迷わないように注意しながら読み進める必要があります。
しかし、4年前に読んだときは読書会で少しずつ読んでいく形式で進めていたので、途中で日を開けたことにより記憶が薄れて何をやっていたのかわからなくなって諦めてしまいました。
しばらくそのままになっていましたが、先月の社内のイベントで同僚から『Go言語でつくるインタプリタ』をOcamlで実装したという話を聞き、わたしももう一度やってみたいと思い立ち再開することにしました。
今回再開するにあたっては注意したのは下記の点です。
- 数日で一気に読み切ること
- 節の区切り、実装の区切りごとに差分をわかりやすく表示すること
- 後から振り返ることができるように差分を保存すること
これらを実現するのに、GitHubのリポジトリを作ってPull Requestを出しながら読んでいくのがぴったりでした。
Pull Requestの差分を利用するメリット
差分が見やすい
紙面上のコードを見ただけで追加・削除などの変更差分がはっきりと浮かんだらいいのですが、わたしはうまくできません。 本の中のコードはだいたい大きさが小さく、差分が赤や緑でわかりやすく表示されることもないので、どうしても目が滑ります。 GitHubのPull Requestを利用すると、見慣れたツール上の見慣れたUIで差分を見ることができて、説明がかなりわかりやすくなります。
また、段落やまとまり単位でPull Requestにすることによって、後から特定の章や節の内容を振り返るのも簡単です。
『Go言語でつくるインタプリタ』は章ごとに字句解析器や構文解析器などを実装していくので、Pull Requestには実装する内容に合わせたラベルをつけました。これで構文解析器を実装した後にREPLを拡張する、といった説明もわかりやすくまとめ、後から振り返ることができるようになりました。
メモが取りやすい
GitHubのPull Requestは行ごとにコメントをつけられるので、細かい単位でメモすることが可能です。 コードにコメントアウトとして残してもよいのですが、一度コードを書いてPull Requsetを出す -> 本を読み返す -> 改めてわかったことをコメントを使ってメモするという手順で、その場で振り返りができます。
また、本の特定のページの説明をコードと一緒に後から参照できるようにしたい場合は、Pull Requestにスクリーンショットや写真、コピーしたテキストを貼っておけばまとめて保管ができます。
最初に読んだときもGitHubを利用したのですが、より作業を簡易にするため、Pull Requestは作らず章や節の区切りの単位でcommitするようにしていました。しかし、Pull Requestにした方が一手間かかるとしても、後から一覧して振り返ることができ(前述のようにラベルをつけることもできる)、またメモを取れるので優れていました。
紙の本に直接書き込んだりアプリでメモしたものはどこにあるか探すのが大変になりがちですが、GitHubのリポジトリを作って保管しておけば、メモをロストすることもありません。
あとから振り返りやすい
Pull Requestにラベルをつけておくことで、ボリュームがあり少しずつ読み進める必要のある章がすぐにわかりました。
『Go言語でつくるインタプリタ』は大きく分けると「1. 字句解析」「2. 構文解析」「3. 評価」「4. インタプリタの拡張」に分けられます。4章は1-3章の内容が入り混じっている章です。
Pull Requestをラベルでソートして数えると、下記の結果になりました。
- 字句解析: 8
- 構文解析: 21
- 評価: 21
初回は構文解析の章で挫折したというところまではわかっていたのですが、改めて振り返ると構文解析の章のボリュームが大きいことがわかります。
また、別途で難しいと感じた実装にはそれとわかるようにラベルをつけ、後から振り返れるようにしました。改めてラベルを確認すると、難しいと感じたところは構文解析の章に集中していました。
すべての本に向いている方法ではない
今回紹介した手法が効果を発揮するのは、コードを追記していく「つくって学ぶ」タイプの本です。
わたしは今年『実用Go言語』と『詳解Go言語Webアプリケーション開発』を読む際に、同じ方法を試しました。『実用Go言語』はつくって学ぶタイプの本ではないので、サンプルコードを写経したり試したりするのに別の方法が向いていると感じました。Go言語にはThe Go playgroundというコードを実行して試す場所があるので、途中からこれを利用するようにしました。
『詳解Go言語Webアプリケーション開発』は中盤から後半にかけて1つのWebアプリケーションをつくってブラッシュアップしていくので、Pull Requestを利用した読書法が向いていると感じました。
どちらの本も今年読んで良かった本です。
著作権への注意
この方法を試す際には、本の中のコードやテキストをそのまま公開しないように注意が必要です。Publicリポジトリを利用して公開すると著作権違反に当たるので、Privateリポジトリを利用します。
なお、事前にGitHubの利用規約を読んで違反していないか確認しましたが、このような利用方法も規約に違反していないようでした。もしわたしが読み落としていて、この使い方が違反に当たることがあれば教えてください。
おわりに
あらゆる本について、座って一読しただけで頭に入ればいいなといつも夢見ているのですが、そううまくはいきません。地道に写経したり、何度も読み返したり、ある程度わかったら読み飛ばしてまたいつか読めばいいと割り切ったり、いろいろ工夫して自分にあった手法を編み出すと楽しいです。
ちなみに『Go言語でつくるインタプリタ』を読了した感想は2年前のゆーすけべーさんのブログに書いてある感想とまったく同じでした。学びながら楽しく実装できる名作だと思います。
以前は挫折した構文解析の章を乗り越えて評価の章に入ったら、章の頭に「この章が一番楽しい」と書いてあって笑ってしまいました。今後も、一度うまくいかなくても諦めずに挑戦したいです。