Ruby Freaks Lounge

第7回小規模Webアプリのためのフレームワーク、Sinatra

はじめに

あなたは「Ruby」と聞いて最初に何を思い浮かべますか? オブジェクト指向スクリプト言語であること、プログラミングの「楽しさ」を重視して設計された言語であること、最近新しいバージョンである1.9.1がリリースされたこと……。

Rubyにはいろいろな特徴がありますが、Rubyという単語からすぐに「Ruby on Rails」を思い出す方も多いのではないでしょうか。Ruby on Rails(以下Rails)は2004年に公開されたRuby用のWebアプリケーションフレームワークで、その生産性の高さから注目を浴び、Rubyの名前を広めることにも大きく貢献しました。

ですが、Java、PHP、Perl、Pythonなど、他の言語の世界ではいくつものフレームワークがしのぎを削っているのに対し、Rubyの世界においてはRailsの完成度の高さから、長らくライバル不在の状況が続いてきました。けれども、競争がないことは必ずしも良いことではありません。互いに機能・性能を競い合うことによって、それぞれのフレームワークの完成度が高まることもあるからです。

幸いなことに最近のRuby界では、個性的なフレームワークがいくつも生まれています。これから数回に渡って、それらの新しいWebアプリケーションフレームワークのいくつかをご紹介したいと思います。気軽にお付き合いいただければ幸いです。

Rails以外のフレームワーク

では、Rails以外のフレームワークにはいったいどんなものがあるのでしょうか? Ramaze Wiki「Other Frameworks」を見てもらえば分かるように、実は意外とたくさんのフレームワークが存在します。その中でも特に活発に開発されているのが、以下の4つのフレームワークです。

Merb
軽量かつ高機能なフレームワーク。次期バージョンはRailsと統合されるという発表で世界を驚かせた。
Waves
DSLを駆使したREST指向のフレームワーク。gihyo.jpにも紹介記事がある。
Ramaze
シンプルであり、好きなライブラリと組み合わせられることを重視したフレームワーク。
Sinatra
DSLを使って、アプリケーションを簡潔に記述することを目指したフレームワーク。

Rack

余談ですが、このようにいろいろなWebフレームワークが開発されているようになった背景に、Rackというライブラリの存在があります。

Railsの登場以前は、RubyでWebアプリケーションを書こうと思えば、Apache上でCGIスクリプトとして実装するのが一般的でした。ところがRailsの登場により、Apacheだけでなく、さまざまなWebアプリケーションサーバが広く使われるようになりました。例えばRuby標準添付のWEBrickに、Mongrel、Thin、Passenger(mod_rails)など、今やいくつもの候補から目的に合ったものを選ぶことができます。

しかし、Webフレームワークの作者にとっては、これらのサーバの全てに対応するのは面倒な作業でした。それを解決するのがRackです。

RackはPythonのWSGIやPerlのHTTP::Engineに似て、WebフレームワークとWebアプリケーションサーバの間をとりもつライブラリです。具体的にはWebアプリケーションを「リクエストを受け取って、レスポンスを返すもの」のように単純化して考え、サーバと情報をやりとりする部分をRackが担当することで、Webフレームワークの側ではリクエストからレスポンスを生成する作業に集中することができるようになっています。

上で紹介したフレームワークはどれもこのRackを内部で利用しているため、Webアプリケーションの開発者は自分の好きなWebアプリケーションサーバを使うことが出来ます(Railsも、バージョン2.3からRackを利用するようになっていますね⁠⁠。

Sinatra

さて、今回と次回の2回は、Sinatraというフレームワークについて紹介したいと思います。Sinatraは他のフレームワークと違い、小規模なアプリケーションに特化したフレームワークで、CGIスクリプト時代のような気軽さでアプリケーションを作ることが可能になっています。

例:Hello World

Sinatraで書かれたWebアプリケーションの例を見てみましょう。画面に「Hello, world!」という文字列を表示するアプリケーションは、Sinatraを使うと以下のように書くことができます。

リスト1 SinatraによるHello Worldアプリケーション
require 'rubygems'
require 'sinatra'

get '/' do
  'Hello, world!'
end

ライブラリのロード部分を除けば、わずか3行でアプリケーションができてしまいます。この簡潔さがSinatraの魅力です。

「get」というメソッドはSinatraが用意しているもので、指定したパスにHTTPのGETメソッドでアクセスされた時に、どんな動作をするかを記述できます。

インストール

では、このアプリケーションを実際に動かしてみましょう。RubyGemsがインストールされた環境ならば、以下のコマンドでSinatraをインストールすることができます(Ruby 1.9でも同様です。FAQには未対応と書かれていますが、基本的な部分は既に動作するようです⁠⁠。

図1 Sinatraのインストール
gem install sinatra

試しに先ほどのHello Worldアプリケーションを「hello.rb」というファイルに保存し、以下のコマンドを実行してみてください。

図2 Hello Worldアプリケーションの起動
ruby hello.rb

MongrelやThinなど、お使いの環境にインストールされているWebアプリケーションサーバが(無ければWEBrickが)自動的に起動します。ブラウザでhttp://localhost:4567/を開くと、⁠Hello, world!」というメッセージが表示されます。

より高度な例

メッセージを表示することはできたので、次はブラウザから情報を送信してみましょう。hello.rbを起動したまま、内容を以下のように書き換えてみてください。Sinatraにはソースコードを自動的に再読み込みする機能があるので、いちいちhello.rbを再起動することなく開発を続けることができます。

リスト2 SinatraによるHello Worldアプリケーション(バージョン2)
require 'rubygems'
require 'sinatra'

helpers do
  include Rack::Utils; alias_method :h, :escape_html
end

template :layout do
  "<html><body><h1>Hello World</h1><%= yield %></body></html>"
end

get '/' do
  erb %{
    <p>あなたの名前は?</p>
    <form action='/hello' method='POST'>
    <input type='text' name='name'>
    <input type='submit' value='送信'>
    </form>
  }
end

post '/hello' do
  erb %{
    <p>こんにちは、<%= h params[:name] %>さん!</p>
    <a href='/'>戻る</a>
  }
end

ブラウザでhttp://localhost:4567/にアクセスすると、名前を尋ねるフォームが表示されます。フォームに名前を入れて送信ボタンを押すと、http://localhost:4567/helloが表示され、さきほど入力した名前を含むメッセージを見ることができます。

Sintraのいろいろな機能

ソースコードの中身を簡単に解説しておきます。このアプリケーションは、4つのメソッド呼び出しでできています。即ち、helpers、template、get、postメソッドです。

helpersメソッドを使うと、アプリケーション内で共通に使うメソッドを定義することができます。ここではHTMLタグのエスケープを行うhという関数を定義しています(このテクニックはSinatraのFAQを参考にしました⁠⁠。

templateメソッドは、MVCでいう「ビュー」の部分を定義します。ビューには名前を付けることができますが、⁠:layout」という名前は特別で、htmlタグなど各ビューで共通に使用される部分が定義されます。ここではh1タグを使って、⁠Hello World」というページタイトルを全ページに表示するようにしています。

getメソッドは先ほど説明した通りです。最初のhello.rbでは単純に文字列を返していましたが、ここではerbメソッドを使っています。erbメソッドを使うと、⁠<%= %>」のような特殊なタグを使って、HTMLに情報を埋め込むことができます(今回は埋め込み機能は使っていませんが、先ほどのlayout機能を有効にするためにerbメソッドを通しています⁠⁠。

ちなみに「%{}」というのはRubyで文字列を記述するための特殊な方法で、ダブルクオートを使った文字列リテラルと機能は同じですが、文字列内の「"」をバックスラッシュでエスケープしなくても良いところが便利です。

postメソッドはgetメソッドと似ていますが、HTTPのPOSTメソッドでアクセスされたときの動作を記述します。ブラウザから渡されたパラメータは、paramsメソッド経由で参照することができます。

Sintraのその他の機能

今回は紹介しませんでしたが、Sinatraには他にもさまざまな機能があります。その一部を以下に紹介しておきます。Sinatraの公式サイトにて、それぞれの詳細を読むことができます。

  • 静的ファイルの表示
  • テンプレートエンジンの使用
  • ユニットテストのサポート
  • コマンドラインオプション(ruby hello.rb -h としてみてください)

まとめ

Ruby界にはRailsだけでなく、さまざまな個性を持ったWebアプリケーションフレームワークが登場しています。今回はそれらの簡単な紹介と、中でも小規模なWebアプリケーションを短時間で作るのに向いたフレームワークSinatraの概要を解説しました。

次回は、Sinatraを使って実用的なアプリケーションを作ってみる予定です。お楽しみに!

おすすめ記事

記事・ニュース一覧