Ruby/Railsのコードを読むにはroccoとrdefsが便利
新年明けましておめでとうございます。今年こそRuby/Railsをやってみようという人もいるかと思います。ここではRubyのコードを読むのに便利なツールを2つほどご紹介したいと思います。
ドキュメント生成ツールのRD、RDoc、SDoc
ソースコードに埋め込んだコメントを、そのままドキュメントとして抽出するツールがRubyにはいろいろあります。いちばん古くからあるのは、RD(Ruby Document Format)と呼ばれるもので、Markdownなどと同様に構造を記述できます。
現在、Rubyに標準添付されているのはRDocです。RubyのソースコードからHTML+CSS+JavaScriptを吐き出して、ブラウザで閲覧しやすくしてれます。もう1つ、RDocに似たものにSDocがあります。Sはsearchableのことで、ブラウザ上でクラスやメソッド名をインクリメンタル検索できるのが特徴です。Railsapi.comに行けば、RubyやRailsの検索可能なドキュメントがあります。SDocは、「gem install sdoc」として、適当なファイルを食わせてローカルで使うこともできます。
全体を読みたいときにはrocco
RDocやSDocは、どんなクラスやメソッドがあって、どういうAPIになっているのかというのを調べるときには良いのですが、ソースコードを上から読むためのツールではありません。
最近のRuby/Rails文化では、コメントが丁寧に書かれる傾向があるように感じています。かなりの量の文書が埋め込まれていて、ファイルによってはコード量よりも文書のほうが多いことも珍しくありません。ぱっとエディタで開いて眺めたき、実質的なコードが3、4行しか目に入らないこともあります。こういうときに全体を眺めるのに良いのが、rocco、rdefsの2つです。
JavaScript界隈では最近、CoffeeScriptで書かれたドキュメント生成ツールの「Docco」の利用が増えいているように思います。ドキュメント部分をブラウザの左側、それに対応するコードを右にコードハイライトして表示するというツールですが、非常に読みやすいです。こういうツールを見ていると、ますますHTML+CSS+DOMは、もはや現代の標準入出力なんだなという気がします。
doccoはCoffeeScriptで書かれていますが、Rubyにも移植されています。それが「rocco.rb」です。コードハイライトにはPygmentsを使っていますので、ローカルにPythonを入れておきます(入れなくても、http://pygments.appspot.com/ のWeb APIでハイライトさせるようですが)。例えば、
$ rocco -l Ruby -o ~/Desktop/spork gems/spork-0.9.0.rc9/lib/**/*rb
などとやると、以下のようにHTMLファイルを生成してくれます。ドキュメントとコードが綺麗に左右に分かれていますね。
ブラウザ右上に表示される「JUMP TO …」にマウスカーソルをのせると、ドロップダウンメニューが出てきてファイル間の行き来もサクサクできて、いい感じです。
ちなみに、rocco.rbを見ると、外部依存のMarkdownライブラリとして、RedCarpet、RDiscount、BlueClothのいずれかをrequireするようになっているように見えますが、私の環境(Mac OS X/Lion/rvm1.10.0/ruby1.9.3-p0)では、Markdown定数が初期化されずにエラーが出ました。なので、rocco.rbに手で
#### Prerequisites
require 'rdiscount'
Markdown = RDiscount
を書き加えました。
構造をぱっと把握したいときはrdefs
「Rubyソースコード完全解説」「ふつうのHaskellプログラミング」などの著書で知られる青木峰郎氏作の「rdefs」というスクリプトも便利です。rdefsはソースコードのclassやmodule、defといった宣言のラインを引っ張り出してくれるツールです。これをEmacsなどのエディタから呼んでコードハイライトさせる環境を作っておくと、*rbファイルを開いた直後に取り敢えずrdefsで全体を見るということが手軽にできます。
rdefsは青木峰郎氏のサイトにありますが(リンク)、青木氏の事後承諾を得て私がGem化したものは、
$ gem install rdefs
でインストールすることもできます。このgemのetc/の下に、私が使っているEmacs用の設定をrdefs.elとして入れてありますが、ヘビーなEmacs使いの人であれば、ディノオープンラボラトリのkmoriさんが公開されているanything向けのanything-rdefs.elのほうが良いかもしれません。rdefsには、catのように行数を出力する-nオプションがあるのですが、anything-rdefs.elでは、この行数を見て定義場所にジャンプしてくれるそうです。
コードを読むといえば、このほかにもタグジャンプやデバッガを使ったりするというのもありますね。Rubyだと、そこまであれこれツールを揃える必要はないのかもしれませんけど。