Rakeが熱い

Rakeにハマり中。こいつ、面白いし、使いやすい。

Rakeとは、Ruby実装のMakeというか、それを超えたツールである。Martin Fowlerがこれを気に入っていて、紹介ページを作っていたりする。
プログラマであれば、誰でも何かしらのビルドツールを使ったことがあると思う。C/C++であればMakeだし、JavaであればApache Antを使うだろう。IDEが発展した現在ではあるが、複雑なビルドを一手順で実現するバッチ形式のビルドは変わらず必要とされる。

ところで、俺はMakeもAntも使用した経験があるが、どちらも物足りなさを感じていた。

Makeはちょっと複雑なことをしようと思えばすぐにシェルスクリプト頼みとなってしまうし、Makefile内にシェルスクリプトを書こうと思えば、エスケープ連発の何か不自然な書き方になってしまう。また、実行環境に備わっているコマンドを呼び出すだけなので、貧弱なコマンドしか持たないWindows環境ではとても使いづらい。なにより、タブで始まった行はコマンド、などという間違いやすい文法が気に入らない。

AntはJava実装された環境非依存のビルドツールで、機能も豊富であるが、こいつに普通のプログラム的なこと・・・条件分岐やループ・・・を書こうと思うと、また気持ち悪い書き方を強要される。Antではビルド定義をXMLで書くが、XMLはこうしたプログラム的な処理を記述するのには全然向いていない。自分でタスクを定義することもできるが、後に他者に引き継ぐことを考えると、あまり余計なプログラムを組み入れたくない。

で、Rakeである。

Rakeのビルド定義はRakefileという名前のファイルとして作成され、中身はMakefileに似ている。

Makefileはこう。

default: hello

hello: hello.o foo.o bar.o
    cc -o $@ hello.o foo.o bar.o

hello.o: hello.c
    cc -c hello.c

foo.o: foo.c
    cc -c foo.c

bar.o: bar.c
    cc -c bar.c

対して、Rakefileはこう。

task :default => "hello"

file "hello" => ["hello.o", "foo.o", "bar.o"] do |t|
  sh "cc -o #{t.name} #{t.prerequisites.join(' ')}"
end

file "hello.o" => "hello.c" do |t|
  sh "cc -c hello.c"
end

file "foo.o" => "foo.c" do |t|
  sh "cc -c foo.c"
end

file "bar.o" => "bar.c" do |t|
  sh "cc -c bar.c"
end

ぱっと見た感じでは、Rakefileのほうが複雑になっており、単に面倒になるだけの気もする。しかし、驚くべきは、このRakefileruby -cに食わせるとSyntax OK.になる点だ。つまり、Rakefileは見た目独自の言語で書かれているように見えるが、実は完全にRubyの文法に準拠したRubyスクリプトなのだ。

こうした実装形式を内部DSLと呼ぶ。これに対して、MakeやAntのように独自の言語を用いるタイプは外部DSLと呼ぶ。

内部DSLを採用したRakeは、ビルド定義中のどこであっても、Rubyという言語(とライブラリ)が持つあらゆる機能をそのまま使用することができる。そして、Rubyオブジェクト指向言語としての高い完成度と、スクリプト言語としての簡便さを兼ね揃えた実に扱いやすく強力な言語だ。

これは実に助かる。MakeとAntに対して抱いていた不満が同時に解消される。文法は説得力がある。なにか複雑なことをしたいときも、いちいちプラグインを別に書いて追加してやる必要もない、直接Rakefileに書けばよいのだ。サブルーチンも使える、クラスも書ける。拡張は自由自在。

俺がAntを使う理由のほとんどは、強力なfilesetを使いたいが為であったが、それ相当の機能がRakeにもある(FileList)。もはや移行をためらう理由はない。

仕事でいくつかRakefileを書いて使っているが、実に扱いやすい。ビルドしたファイルをFTPで転送するのも簡単、特定のファイルの中身に変換をかけるのも正規表現を使えば楽勝、etc, etc,...と、実に役に立っている。

難点は、Rakeは当然ながら、Rubyもあちこちの環境に標準で搭載されている代物ではない、という点か。使いたければ、自分でインストールしなければならない。もっとも、rubygemsPerlでいうCPANみたいなことができる)経由で入れれば良いだけなので、大した苦労はないのだが。

あと、日本語の情報がほとんど無い。英語のマニュアルを読むのに慣れていれば、別に難しいツールではないので覚えるのは簡単なのだが、嘆かわしいことにプロのエンジニアの世界でも苦手な人間がほとんどだ。

追記:無いので書きました

Rakeは複雑なビルドの実装に四苦八苦するエンジニアへの福音となるかもしれない。どう利用していこうかという研究もちらほら見かける。まだ世に出て間もないので、導入は易しい作業ではないが、試してみる価値はある。内部DSLという代物を知る教材としてもいいかもしれない。