第3回 話題騒然! 「言語内DSL」の概念とRake【前編】:Ruby on Rails究極指南(2/2 ページ)
近年、特定の領域に存在する問題の解決に特化してデザインされたコンピュータ言語「DSL」が注目を集めている。本稿では、RubyとDSLの関係について解説していく。Railsによって注目を浴びたRakeを取り上げて、DSLの概念やRakeの特徴、その使い方などを説明する。
ビルド言語の分類とRake
DSLはスタイルによって幾つかに分類できますが、ここではプログラミング言語指向のものに注目します。プログラミング言語指向のDSLは、言語内(internal)DSLと異語外(external)DSLに大別できます。言語内DSLとは実行時に利用される言語(ホスト言語)とDSLが同じものを、言語外DSLはホスト言語とDSLが異なるものを指します。いずれも以前から行われているアプローチであり、例えば言語内DSLはLispやSmalltalkで、言語外DSLは多くのUNIXツール(例えばawkやprocmail、PostScript)で使用されています。
マーティン・ファウラー氏は、make、Ant、Rakeの各ビルド言語をDSLのスタイルに従って次のように整理しています。
- make:独自文法による言語外DSL
- Ant:XMLを言語として利用した言語外DSL
- Rake:Rubyによる言語内DSL
DSLとしてホスト言語を利用するメリットは、学習コストの節約と、ホスト言語の文法や機能、周辺ツールを活用できる点にあります。「ドメインに特化した言語」という観点からはデメリットともなりますが、ビルドツールのようなユーザー層がプログラマーである分野では、デメリットよりもメリットの方が大きいでしょう。
Rakeの簡単な使い方
それでは、実際にRakeを使ってみましょう。Railsが導入済みであれば、Rakeもすでにインストールされています。Rakeが正常にインストールされているかどうかは、rakeコマンドを実行することで確認できます。
$ rake --version
rake, version 0.7.2
なお、ヘルプを表示したい場合は、「--help」オプションを指定します。
ビルドするプログラムの概要
ここでは、Cで書かれた「Hello World」を出力するプログラムをビルドします。ソースコードの内容は省略しますが、全体の依存関係が図2のようになっているケースを想定します。
コンパイル対象のソースコードとヘッダファイル、RakeのビルドファイルであるRakefileは、すべて同じディレクトリに配置しておきます。
$ ls
greet.c greet.h main.c rakefile
Rakefileの記述例
helloプログラムをビルドするには、リスト1のようなRakefileが必要となります。Rubyの基本的な文法を理解していれば、Rakeの詳細を知らなくても処理内容が読み取れるのではないでしょうか。Rakefileの内容は次のとおりです。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
1行目では、Rakeがビルトインで提供しているcleanタスクを読み込んでいます。2行目では、cleanタスクで削除対象とするファイルを配列で指定しています。ここでは最終成果物であるhelloと、*.cをコンパイルして生成するオブジェクトファイルが削除対象です。
4行目は、rakeコマンドを引数なしで起動した場合に実行されるデフォルトのタスクです。Rakeの基本的な文法は、
task タスク名 => [依存タスク] do
処理内容
end
というものです。タスク名の指定にはシンボルを使用することに注意してください。
6行目以降では、ビルドに必要な各処理をそれぞれタスクとして定義しています。「task」ではなく「file」と記述しているのは、ファイル生成に特化したタスクだからです。Rakeではこれを「ファイルタスク」と呼んでいます。ファイルタスクが通常のRakeタスクと異なる点は次の2つです。
- タスク定義では「task」の代わりに「file」と記述
- ファイルタスク名はシンボルではなく文字列で指定
ブロックには、ファイルタスク名で指定したファイルを生成するための処理を記述します。「sh」はRakeが提供しているメソッドであり、与えられた文字列をシステムコマンドとして評価・実行します。
なお、実際にRakeを利用する際には、タスク定義の重複個所は「ルール」と呼ばれるRakeの機能や、Rakeが提供する変数などを使ってパターン化できます。この例では説明を簡単にするため、重複個所はそのままにしてあります。
ファイルタスクと同様の位置づけのタスクとして、ほかに「ディレクトリタスク」が提供されています。名前のとおり、ディレクトリの生成に特化したタスクです。書式は、
directory "ディレクトリ名"
であり、ディレクトリ名はファイルタスクと同様に文字列で指定します。
- rakeコマンドによるビルドの実行
Rakefileで定義したタスクを実行するには、Rakefileを置いたディレクトリでrakeコマンドを実行します。リスト1のRakefileではdefaultタスクを定義しているので、引数なしで起動するとhelloのファイルタスクが実行されます。
$ rake
(in /path/to/rakefile/directory)
cc -c -o main.o main.c
cc -c -o greet.o greet.c cc -o hello main.o greet.o
生成されたファイル群を確認し、helloが実行できることを確認します。
$ ls
greet.c greet.h greet.o hello main.c main.o rakefile
$ ./hello
Hello, World
再度rakeコマンドを実行しても、ファイルに変更がなければ何も実行されません。そこで、greet.oを削除してからrakeを実行してみると、
$ rm greet.o
$ rake
(in /path/to/rakefile/directory)
cc -c -o greet.o greet.c
cc -o hello main.o greet.o
のようにgreet.oが再生成され、greet.oに依存しているhelloが再コンパイルされます。これによって、Rakefileに記述した成果物の時系列的な依存関係がRakeによって解決されていることが分かります。
cleanタスクを実行すると、削除対象としたファイルが削除されます。
$ rake clean
(in /path/to/rakefile/directory)
rm -r hello
rm -r main.o
rm -r greet.o
$ ls
greet.c greet.h main.c rakefile
次回は
すでに紹介したとおり、言語内DSLはホスト言語そのものを利用してDSLを構築します。したがって、言語内DSLではホスト言語の機能をフル活用できます。Rubyで構築された言語内DSLであれば、Rubyの制御構造の利用はもちろん、独自にクラスやメソッドを定義できますし、サードパーティーのRubyライブラリを利用することも可能です。次回はこのあたりを解説します。
本記事は、オープンソースマガジン2006年3月号「Ruby on Rails 1.0の世界」を再構成したものです。
関連記事
- developersLife〜開発者という生き方
- 連載第2回:Rails専用IDE「RadRails」でRailsをもっともっと快適に
いくらRailsが「less code」をキャッチコピーに使っているとはいえ、まったくコードを書かなければ何も起きません。今回は、コードを書くための環境として、Rails専用IDEである「RadRails」を取り上げる。 - 連載第1回:Instant Railsで始めるWindows環境のRails
世界中でRubyの人気が急上昇しているが、このきっかけの1つとなったのがWebアプリケーションフレームワークRuby on Rails(Rails)である。本連載では、このRailsの特徴や魅力を余すところなく伝えていく。 - まつもとゆきひろ――第1回:オープンソースという「お仕事」
- まつもとゆきひろ――第2回:Rubyを開発するということ
- まつもとゆきひろ――第3回:僕の存在価値はそこにある
- Webアプリケーションの開発手法で「早くてキレイ」はRuby on Railsか
「美しいが作るのに時間の掛かる」「汚いが早く作ることができる」――Webアプリケーションの開発手法としてあなたが選択したいのはどちらか? 答えはどちらでもない。Ruby on Railsはある考えに沿って進める限りにおいて「早くて美しい」開発手法を提供してくれるのだから。
関連リンク
- developerWorks
- Ruby on RailsによるWebアプリケーションの高速開発
迅速な開発のためのこのRubyベースのフレームワークでは、モデル/ビュー/コントローラー・パターンが使用されている。 - 境界を越える:Ajax on Rails
Webページの対話性を高める技術、Ajaxに対する熱狂が、さらに高まっています。またRuby on Railsフレームワークの人気も高まっていますが、その理由の1つはAjaxと非常にうまく統合できるという強みがあるためです。Ajax on Railsが、なぜそれほど強力な組み合わせなのか、この記事で学びましょう。
Copyright © ITmedia, Inc. All Rights Reserved.