読者です 読者をやめる 読者になる 読者になる

すがブロ

sugamasaoのhatenablogだよ

sinatra のマニュアルをちゃんと読んでみた

ruby sinatra

sinatra はシンプルで分かりやすい

ちょっと使うには sinatra の使い方が日本語でも普通にあるので、大して困らないですよね。

ここら辺があれば、sinatra 自体もある程度使えるし、passenger を使ってサーバにデプロイして運用するのも困らない。

そのため

公式のマニュアルって読んでなかったんですけど、改めて見てみると分かりやすいので、読んでない人は一読しておいた方が良いでしょう。

読んでいて発見した点

ローカル変数をテンプレート内で使用することができる

下記のように、 :local => {} でローカル変数をテンプレート内で扱えるようにできるみたいです。

  get '/:id' do
    foo = Foo.find(params[:id])
    haml '%h1= foo.name', :locals => { :foo => foo }
  end

このやり方は他のテンプレート内で部分テンプレートとして表示する時に典型的に使用されます。

強制終了

ルートかbeforeフィルタ内で直ちに実行を終了する方法:

  halt

body部を指定することもできます …

  halt 'ここにbodyを書く'

ステータスとbody部を指定する …

  halt 401, '立ち去れ!'

リクエストパラメータのエラーとか、何か例外があって即座に止めたい場合に使えば良いのだろうか。

パッシング(Passing)

ルートはpassを使って次のルートに飛ばすことができます:

  get '/guess/:who' do
    pass unless params[:who] == 'Frank'
    "見つかっちゃった!"
  end

  get '/guess/*' do
    "はずれです!"
  end

役に立つ局面がパッと思い浮かばないけど、共通の処理をさせたい時とかに役に立ちそう。

設定

どの環境でも起動時に1回だけ実行されます。

  configure do
    ...
  end

環境変数:production(RACK_ENV環境変数) がセットされている時だけ実行する方法:

  configure :production do
    ...
  end

環境変数:production か:testの場合に設定する方法:

  configure :production, :test do
    ...
  end

これは Rails でもあるような感じですね。というか、 configure メソッドとかあったんですねー。

エラー

error ハンドラーはルートブロックかbeforeフィルタ内で例外が発生した時はいつでも発動します。 block or before filter. 例外オブジェクトはRack変数sinatra.errorから取得されます。

  error do
    'エラーが発生しました。 - ' + env['sinatra.error'].name
  end

エラーをカスタマイズする場合は、

  error MyCustomError do
    'エラーメッセージ...' + request.env['sinatra.error'].message
  end

と書いておいて,下記のように呼び出します。

  get '/' do
    raise MyCustomError, '何かがまずかったようです'
  end

そうするとこうなります:

エラーメッセージ... 何かがまずかったようです

開発環境として実行している場合、Sinatraは特別なnot_foundとerrorハンドラーをインストールしています。

こんな感じでエラーや notfound をカスタマイズできるんですね。なんとなく知ってはいたものの、使った事なかった><

テスト

SinatraでのテストはRack-basedのテストライブラリかフレームワークを使って書くことができます。 Rack::Test をおすすめします。やり方:

  require 'my_sinatra_app'
  require 'rack/test'

  class MyAppTest < Test::Unit::TestCase
    include Rack::Test::Methods

    def app
      Sinatra::Application
    end

    def test_my_default
      get '/'
      assert_equal 'Hello World!', last_response.body
    end

    def test_with_params
      get '/meet', :name => 'Frank'
      assert_equal 'Hello Frank!', last_response.body
    end

    def test_with_rack_env
      get '/', {}, 'HTTP_USER_AGENT' => 'Songbird'
      assert_equal "あなたはSongbirdを使ってますね!", last_response.body
    end
  end

注意: ビルトインのSinatra::TestモジュールとSinatra::TestHarnessクラスは 0.9.2リリース以降、廃止予定になっています。

Rack::Test がうまいこと使えるようになっているんですね。知らなかった・・・!

コマンドライン

ローカル環境で実行する場合は、コマンドラインから sintara を起動させるのだけど、そのオプションもいろいろある。

-h # ヘルプ
-p # ポート指定(デフォルトは4567)
-e # 環境を指定 (デフォルトはdevelopment)
-s # rackserver/handlerを指定 (デフォルトはthin)
-x # mutex lockを付ける (デフォルトはoff)

これを機に

もうちょっと sinatra を使い込んで行きたいですね。
あと、 Rack の機能もあまり知らない/(^o^)\ので、もうちょっと活用したいな。
例えば、HTMLのエスケープとか、ログ周りとか。