第4回 話題騒然! 「言語内DSL」の概念とRake【後編】:Ruby on Rails究極指南
近年、特定の領域に存在する問題の解決に特化してデザインされたコンピュータ言語「DSL」が注目を集めている。本稿では、前回に引き続いて、RubyとDSLの関係について解説していく。
この連載のバックナンバーは以下の通りです。併せてお楽しみください。
連載第1回:Instant Railsで始めるWindows環境のRails
連載第2回:Rails専用IDE「RadRails」でRailsをもっともっと快適に
連載第3回:話題騒然! 「言語内DSL」の概念とRake【前編】
言語内DSLとしてのRuby
前回紹介したとおり、言語内DSLはホスト言語そのものを利用してDSLを構築します。したがって、言語内DSLではホスト言語の機能をフル活用できます。Rubyで構築された言語内DSLであれば、Rubyの制御構造の利用はもちろん、独自にクラスやメソッドを定義できますし、サードパーティーのRubyライブラリを利用することも可能です。
DSLからのRubyの利用
Rakefileは、実行時にそのままRubyのコードとして評価されます。ここで、前回紹介したhelloプログラム用のRakefile(リスト1)にRubyのメソッドを定義してみましょう。参考までに(リスト1)を再度示しておきます。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
例えば、リスト1の6〜12行目をリスト2のように修正すると、コンパイル部分をメソッドとしてくくり出せます。これを見れば、Rakeのファイルタスクのような成果物間の依存関係の宣言と、コンパイル方法のような具体的な手続きの記述とを、Rakefileに対して違和感なくまとめて簡潔に記述できていることが分かるはずです。ビルド時に必要な処理やその組み合わせが複雑になった場合、Rubyの機能をフル活用できることがRakeの大きなアドバンテージとなります。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
Rubyの表現力
Rubyで実装された言語内DSLの文法の多くは、通常のメソッド呼び出しです。通常のメソッド呼び出しを、あたかもDSL用の新たな文法であるかのように読み書きできるというのがポイントです。このことは、DSLツールの実装者の負担も軽減します。
言語内DSLの文法としてRubyを利用しやすい理由には、次のようなRubyの特徴が挙げられます。
- 省略表記の豊富さ
- 言語レベルでのブロックのサポート
- 拡張に対して開かれたクラス
以下、順番に紹介します。
省略表記の豊富さ
Rubyでは、多くの場合*、文末のセミコロンをはじめとして、メソッド呼び出しの括弧やハッシュのリテラルの記述などを省略できます。省略記述をうまく活用することで、Ruby上では単なるメソッド呼び出しにすぎない記述を、あたかも別の言語による宣言のように見せることができます。
Rakeのタスク記述を、
task :test => [:compile] do
do_task1
do_task2
end
のように書けるのも、Rubyの省略表記のおかげです。この記述は、
task({:test => [:compile]}) {
do_task1();
do_task2();
}
と等価ですが、このように書いてしまうとDSLの文法というよりは、いかにもAPIメソッドの呼び出しのように読めてしまいます。
言語レベルでのブロックのサポート
Rubyでは、メソッド呼び出し時に「do……end」で括ったブロックを渡すことができます。ブロックには特定のコンテキストにおける一連の処理を記述します。
これを利用して、Rakeではタスクの定義にブロックを使います。
task :test do
ruby "test/unittest.rb"
end
タスク定義にブロックを渡すことと、省略表記を活用することで、「task」がメソッド呼び出しというよりはタスク記述用の文法であるかのように見せています。
拡張に対して開かれたクラス
Rubyでは、あらゆるクラスが拡張に対して開かれています。コアライブラリのクラスであっても例外ではありません。これはRailsでの例になりますが、ActiveSupportというユーティリティはコアライブラリのNumericクラスを拡張しています。この拡張によって、Railsでは「現在時刻から20時間前」を「20.hours.ago」と記述できます。
>> 20.hours.ago
=> Fri Jan 13 11:13:13 JST 2006
ActiveSupportのRubyコアライブラリ拡張は容赦がなく、true、false、nilといった表現をするクラスも拡張の対象としています。
言語内DSLとしてのRuby利用の広がり
ここまで読んだ人はすでに気づいているかもしれませんが、現在、最も成功しているRubyによる言語内DSLツールはRailsです。Railsは「Webアプリケーション」という問題を解決するためにRubyを利用しています。もちろん言語内DSLなので、Rails内ではRubyをフル活用できます。「Ruby on Rails」という名前は、「Railsという名のDSLのレールにRubyを乗せて行く」と解釈できるかもしれません。
このようなDSLライクな記述を活用したものはRailsの周辺ツール*でも充実しており、その代表的なものはmigration*とSwitchTowerです。前者はデータベースのスキーマのDDL*を、後者はRailsアプリケーションのデプロイ方法を、それぞれRubyを利用した言語内DSLとして記述します。
ここで、migrationでの簡単なテーブル定義を紹介しましょう。リスト3では、CreateUserTable#upというメソッドと、CreateUserTable#downというメソッドで、テーブルの作成と削除を定義しています(それぞれのSQL記述はリスト4)。これだけでは単にDDL記述を抽象化しているだけですが、migrationではデータベースのスキーマのバージョン管理も実現可能です。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
本稿で紹介してきたツールは、すべてRakeと組み合わせて利用できます。Railsはrailsコマンドで生成したアプリケーションの開発で利用するRakefileを、拡張可能な形式で提供しています。Rake本体の動作とは若干異なるRails流の規約ですが、それに従うことで簡単に拡張できるわけです。
ユーザー定義のRakeタスクをRailsの提供するRakefileと統合して利用するには、ユーザー定義のRakeタスクを記述したファイル(*.rake)をRailsアプリケーションの開発ディレクトリ以下にあるlib/tasksディレクトリに配置すれば完了です。これによって、ユーザー定義のRakeタスクとRailsの提供するRakeタスクとを同じように利用できます。
SwitchTowerは、この仕組みを利用しています。switchtowerコマンドでは、独自のRakeタスクが生成されます。このタスクはRailsアプリケーションの開発で利用するRakefileに統合されるので、違和感なく利用することが可能です。
まとめ
以上、2回にわたってDSLの概念とRakeについて解説してきました。「Rubyを言語内DSL構築用に利用して、簡潔な文法で宣言的な記述と手続き的な記述をうまく取り合わせ、それをRakeと組み合わせる」というケースは、これからもますます増えていくでしょう。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
このページで出てきた専門用語
多くの場合
コンテキストによっては省略できない場合もある。
Railsの周辺ツール
Railsと直接関係ないところではRubiniumがある。
migration
http://wiki.rubyonrails.com/rails/pages/UnderstandingMigrations
DDL
Data Definition Languageの略で、リレーショナルデータベースのテーブルを制御する言語。
本記事は、オープンソースマガジン2006年3月号「Ruby on Rails 1.0の世界」を再構成したものです。
関連記事
- developersLife〜開発者という生き方
- 連載第3回:話題騒然! 「言語内DSL」の概念とRake【前編】
近年、特定の領域に存在する問題の解決に特化してデザインされたコンピュータ言語「DSL」が注目を集めている。本稿では、RubyとDSLの関係について解説していく。Railsによって注目を浴びたRakeを取り上げて、DSLの概念やRakeの特徴、その使い方などを説明する。 - 連載第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.