ソースコードを読む

エンジニアとなり、RubyやRailsのプログラムを読み書きするようになって2年経った。 ソースコードを読む時のワークフローについて考えてみた時に、他人がどのようにソースを読んでいるのが気になった。

どのようにソースを読み、どのように理解するのか、一般解を知る前にまずは自分の方法を整理してみることにした。

ソースを読むメリット

  • 間違いがない
  • APIドキュメントから漏れていること、内部仕様もわかったり
  • StackOverFllowに惑わされない
  • 結果的に迷う時間の短縮

必要なモノ

  • 気合
  • 根性
  • pry
  • bundle open
  • IDE、Ctagsが使えるエディタ(Emacs, Vim, etc)
    • 定義元ジャンプができればOK
  • 言語、フレームワークの公式リファレンス(http://devdocs.io)

武器の使いドコロ

気合

Googleへ逃げず、ソースを読むという決断をするのために必要

根性

ソースコードを読み始めたが、よくわからんと途中で調べる事をやめてGoogleにすぐ逃げてしまうことを避けるために必要

pry

調べたいコードを実行させ、binding.pryでブレークポイントを作る edit METHOD_NAMEがどこから呼ばれているのかを見る。

Rubyのコードは実行時でないと、正しい呼び出し元がわからない。

また、pryはコード・リーディングやデバッグに便利様々な機能を持っている

  • show-source METHOD_NAME でソースを読むこともできる
  • ls OBJECT_NAMEでオブジェクトのクラスメソッド、インスタンスメソッドなどを確認できる

IDEや、Ctagsが使えるエディタ(Emacs, Vim, etc)

定義元にエディタ上でジャンプする

  • これだけのためにIDE使うという人は多い
  • pryのeditで飛んでそこからはエディタでタグジャンプしたりする

Ctags

  • コマンドラインツール
  • エディタがメソッドの定義元を調べるための索引tagsを提供
    • tagsがある場合、vimはデフォルトでc-]押せば定義元にジャンプできる(タグジャンプ)
  • 万能ではなく、ジャンプ先がたまに間違っていることも
  • Gtags(GNU GLOBAL)をいじるともっと賢い索引が手に入るらしい
  • vim使ってる場合は、rails-vimプラグインがRails用にタグ生成コマンドを提供している
  • ファイルサイズが大きく、利用するか否かは個人の環境に依存するため、.gitignoretagsを追加しておくべき。

bundle open

bundle open LIBRARRY_NAME

ライブラリ内のソースの在処(ディレクトリ)を開く README.mdを読んだり、lib/から関係していそうなところをおもむろに開いてみたりしている。 特に自分が使っているバージョンのREADME.mdを読むということに関しては最速。

言語、フレームワークのリファレンス

(好きなツールで) リファレンスをいつでも読めるようにしておくことは重要

自分はDevDocsをよく使う

DevDocsの特徴

  • リファレンスなんでも横断検索ツール
  • Rails, Lodash, jQuery, Angular, Reactなど大抵ある
  • オフライン機能があり、ブラウザにキャッシュさせることで、インターネット接続環境がなくても閲覧できる

最後に

慣れてくれば意外といきなりGoogleで検索するということが減ってくる。 BootstrapやSimpleFormなどのViewまわりのヘルパーを提供するGemを使うときには頻繁にソースコードを読むことが多くなる。 Gemが提供するに同名のメソッドでもって要求する引数の型が異なる場合があるため。

また、ここまで紹介した内容は完全に自己流のため、効率の良い方法があればぜひ教えていただければとm(_ _)m

おまけ

pryを使いやすく

~/.pryrcを作っておくと、使えるエディタ、エイリアスの設定が可能

require 'pry'
Pry.config.editor = "vim"
Pry.config.theme = "tomorrow-night"

if defined?(PryByebug)
  Pry.commands.alias_command 'c', 'continue'
  Pry.commands.alias_command 's', 'step'
  Pry.commands.alias_command 'n', 'next'
  Pry.commands.alias_command 'f', 'finish'
  Pry.commands.alias_command 'ss', 'show-source'
end

VimからDevdocsを開く

" plugin
NeoBundle "tyru/open-browser.vim"
" for open-browser plugin
nmap dx :<C-u>OpenBrowserSearch -devdocs <C-r><C-w> <CR>
vmap dx y:<C-u>OpenBrowserSearch -devdocs <C-R>"<CR>