汎用性の高い技術ポエム Advent Calendar 2015 の3日目の投稿です.
普段はつくったものの紹介とか技術的に調べたことのメモとか勉強会参加記事を書いていて雑感とかは大体ツイッターに書いているんですが,最近どことなく頭にこびりついていることがあるので整理がてらブログに書きます.
とりあえず入門書は読んだ問題
新しい言語やフレームワークを学ぶ動機は様々です. つくりたいものがあってそれをつくるための知識として,言語機能が魅力的だから,流行っているからなどなど… 僕は一番最初の理由で始めることが多いですが,どれが良いとかいう話ではなく Pros Cons があると思います. 例えば僕の場合はつくりたいものが先にあるので体系的に学ぶよりはチュートリアルなどをさっと済ませてしまって動くものに取り掛かるので知識が偏ったりします.
そしてとりわけ後者2つに多いのが「とりあえず入門書は読んだけど次どうしよう」問題だと思っています.実際に「何かつくるアイデア無い?」とか聞かれることはたまにありますし,入門書を読んだだけで終わってしまうケースもあり勿体無いと思います.(僕も身に覚えがあります…) なぜこうなりがちなのか考えてみると,入門は大体皆同じような道を辿って学習するので本にしやすくやることもはっきりしやすくて良いのですが,その後進む方向はより具体的になって人によってばらばらになるからじゃないかなと思っています.
そんなときはプルリク駆動学習?
この「とりあえず入門書は読んだ」問題の次に進むのに,最近「こうすれば良いんじゃないかなぁ」と思っているのが GitHub の Pull Request(プルリク)駆動学習です.ざっとまとめると次のような手順です.
- 入門した言語・フレームワークを使ったプロジェクトで気になるもの,貢献したいものを探す
- そのプロジェクトのコードを読みまくる,何かのツールなら使いまくる
- 小さくても良いので改善点や不満点が出てきたら実際にコードをいじって直してみる
- プルリクエストにしてレビューを受ける
1. 入門した言語・フレームワークを使ったプロジェクトで気になるもの,貢献したいものを探す
学んだ言語・フレームワークで書かれたものを探します.何か気になっているものがあればそれを,無ければ GitHub で検索 します. 何でも良いと思っていますが,次の点に注意するのが良いのかなと思います.
- なるべく小さいものを選ぶ(大きすぎると読むのが大変で 2. で力尽きそうです.1000〜2000行ぐらいが良さそう?)
- 作り捨てられたものではなくメンテされているもの,テストがあるもの
- Issues や Pull requests で活発に反応がある
- マージ前にプルリクエストにレビューが入っている(重要)
- すでに詳しい知人がいれば,その人のプロジェクトとか
2. そのプロジェクトのコードを読みまくる,何かのツールなら使いまくる
読んでいるコードは「同じ言語・フレームワークを使うけれども自分よりも習熟した人」が書いたコードのはずなので,基本的に読むだけでもかなり勉強になると思います. また,(printf などをはさみながら)実際に動かしてみるとどこがどう動いているのか分かって良いと思います.
ここでは,コードの書き方だけでなく,関連ツール群の使い方とかテストの書き方なども読み取れます(なかなかそういうことは入門書には書いていないと思います).
3. 小さくても良いので改善点や不満点が出てきたら実際にコードをいじって直してみる
そうこうしているうちに,「こういうオプションがあると便利なんじゃないか」とか「ここはこうコードを変えたほうが効率が良いんじゃないか」とか「ここ間違ってるんじゃないか」とか出てくると思います.(TODO
とか FIXME
で grep してみるのも有効かもしれません.)
ここでリポジトリを fork し,新しいブランチ(名前は変更内容を反映していると良いですが,小さい変更なら patch-1
とかでも良いと思います)を作成し,実際にコードを足したり修正したりしてみます.
おそらく一発でうまくいかないので,デバッグしたり色々試したりすることになります.新規追加ならその箇所のテストを,修正なら修正できたことが確認できるテストを実際に書いて走らせてみます.
4. プルリクを出してレビューを受ける
GitHub の自分の fork したリポジトリページに行き,プルリク作成ボタンを押します. 自分の変更の目的・理由や変更内容の説明をします.あと,素直に「初心者なのでレビューお願いします」と書いておいたり,レビューしてほしい点をまとめて書いておくとさらに良いかもしれません.
ここで受けるレビューがとても勉強になると思っています.merge する側にとっても修正や機能追加してくれるのはありがたいですし,merge した後は自分がメンテしないといけないコードなので,積極的にレビューしてくれる可能性が高いです. 指摘された箇所はガンガン直していきます.ただし,プルリク作成時は以下の点に注意したほうが良いと思います.
- ローカルでテストが通ることを確認する
CONTRIBUTING.md
がある場合は絶対読む- コードスタイルに気を配る
英語が必要になったりしますが,相手も人間なので頑張れば割と通じます.日本語の issue OK なリポジトリを探してみるのも良いかもしれません(1. がちょっと大変になりますが…) また,3. の時点で書ききれなかった場合でも [WIP] とタイトルの頭につけてとりあえずでプルリクを出し,プルリクの説明中に目的ややりたいこと,どこで詰まっているかを書けばアドバイスがもらえてプルリクを完成出来たりします.
僕の場合
僕の場合は
- とりあえず Tour of Go やってみたので
peco
に smart case 機能を付けてみる - Crystal 言語が気になったので,Crystal の標準ライブラリを読んで修正・追加してみる(Crystal はセルフホスト済み)
- TypeScript の型定義の書き方なんとなく分かったので試しにマイナーな JS ライブラリの型定義を書いてみて, DefinitelyTyped に投げてみる
などなど… どれも学習の助けになったと感じていますし,自分の欲しかった機能が入ったりリリースノートに自分の名前が載ったりして良かったです.
まとめ
GitHub は単なるリポジトリホスティングサービスじゃなく,ある種の SNS だと感じているので,それを学習に生かせるんじゃないかというのが最初の考えでした. もちろん必ずこれでうまくいくと思っているわけではないですが,「とりあえず入門書は読んだけど次どうしよ…」となったときの進め方の1つとして有りなんじゃないかなと思っています. 思っていることを整理しながら考えたのでところどころ偉そうな文になっている気がしますが,僕も分かっていないことだらけなのでもっと実践していきたいです. 「試しにやってみた」とか「ここはこうやったほうが良い」とか「もっと良い方法知ってる」などありましたら,ぜひ教えてもらえると喜びます.
なお,(力不足ですが)僕のリポジトリはどれも日本語 OK プルリク歓迎です.