Edited at

Sinatra-Contribまとめ

More than 1 year has passed since last update.


はじめに

最近まで reloader と json しか使ってなかったですすみません。謝罪も兼ねて、どんな拡張が提供されているのかをまとめておきます。


Contribの中身を知る

主に Readme で触れられているものを順番に確認していくスタイル。


sinatra/capture

テンプレートのレンダリング結果をキャプチャできる(要するに文字列として変数に格納できる) capture メソッドが追加される。

以下のようにして変数 a にレンダリングした結果の文字列を格納できるってことである。

<% a = capture do %>World<% end %>

capture_later とかけっこうマニアックな動きだと思うんだよな。面白いけど。逆にいえば普通の capture だとブロックの中身はその場で即時評価されるのだ。


sinatra/config_file

Yaml ファイルを読み込んで、settings って名前で参照できるようにする config_file メソッドが追加される。

Yaml ファイルの拡張子を .erb にしたりすると設定ファイル内でテンプレート記法が使える。環境変数から情報引っ張ったりするんだろう。なおテンプレートは .erb のみみたいだ。


sinatra/content_for

よそで定義したコンテンツをパーツとして再利用する。capture と違うのはレンダリングするタイミングなのかな。Rails の content_for とだいたい一緒。


sinatra/cookies


Easy way to deal with cookies


って書いてる。リクエストのコンテキスト内だと cookies へアクセスできるようになる。


sinatra/engine_tracking

テンプレートがレンダリングされている最中のエンジンを取得する。使い所はどこだろう。

haml?とかerb?などのヘルパーメソッドが追加される。


sinatra/json

よく使うやつ。

def "/" do

json :name => "akita"
end


sinatra/link_header

HTMLの <link>ヘッダを生成するヘルパーメソッドを追加したり、また response["Link"] という特殊なヘッダが設定されていた場合パースしてlinkヘッダを生成してくれるのだがあまり使わなさそうだ。


sinatra/multi_route

以下のような記法ができるようにルーティングDSLを拡張するもの。カスタムHTTPメソッドもサポートする。

get '/foo', '/bar' do

route :get, :post, ['/foo', '/bar'] do


sinatra/namespace

DSLにnamespaceメソッドが追加される。

以下は公式ドキュメントの例だが、URLの重複記述を避ける、見た目上のブロックのグループ化の他、before, after などのフィルタがそのブロック単位で設定できるので思いの外便利である。

namespace '/admin' do

helpers AdminHelpers
before { authenticate unless request.path_info == '/admin/login' }

get '/dashboard' do
# Only authenticated users can access here...
haml :dashboard
end

# More admin routes...
end

get '/' do
# Any user can access here...
haml :index
end


sinatra/respond_with

Railsの respond_to とだいたい同等の発想で書かれたフォーマットに対して出力を切り替えるための respond_with メソッドを追加するもの。通常 sinatra のテンプレートファイルは index.slim とか help.erb とテンプレート形式の拡張子だけが付くんだけど、こいつを使ったときには help.json.erb とか index.xml.nokogiri という風に出力先のデータ形式の拡張子も含まれるようになる)


sinatra/custom_logger

request.logger もしくは settings.logger へのアクセス方法を提供する。

settings.logger はつまり set :logger, ... で設定できるので、そこに自前のロガーインスタンスを設定せよということのようだ。


sinatra/decompile

コードのコメントにこのように書いている。ということは…。

      # Everything in here is basically just the reverse of

# Sinatra::Base#compile
#
# Sinatra 2.0 will come with a mechanism for this, making this obsolete.

とはいえ、 Sinatra 2.0 なんていつの話なのかっていう指摘もあり。なお、Sinatra::Base#compile はパス文字列を内部的に分割する処理である。

使われ方はこういうやつだ。

pattern, keys           = compile path


sinatra/reloader

導入すると、ファイル更新によって Sinatra アプリケーションをリロードしてくれるもの。

開発/デバッグ時にほとんど必須であろう。直接見ているコードだけではなく、周辺ファイルが更新されてもリロードさせたり、あるいは特定ファイルが更新されてもリロードしないように設定することもできる。


sinatra/extension

Sinatra::Extension を拡張したExtensionの記述方法を簡潔に書けるようにするシンタックスシュガーを提供する。というかいちいち Sinatraモジュール以下に含めて register 呼ぶ手間が省けるだけだけど、やりたいことが明確になるのでこれはとても良い。ナマナマしたメカニズムが隠蔽できる。


sinatra/streaming

Stream処理(手っ取り早く言えば一括でデータを返すんじゃなくてじわじわ送るヤツだ)を書くためのヘルパーを提供する。

以下は公式サイトの例だが、わかりやすい。

get '/' do

stream do |out|
out.puts "Hello World!", "How are you?"
out.write "Written #{out.pos} bytes so far!\n"
out.putc(65) unless out.closed?
out.flush
end
end


sinatra/test_helper

Sinatra::Contribの spec で使われている。これは本当にヘルパーだからコード読んで使えそうなら使う感じだろうなー。


sinatra/required_params

以下のように書ける。指定したパラメータがクエリにない場合に 400 エラーにしてくれる。

   get '/simple_keys' do

required_params :p1, :p2
end


まとめ

ということで、Sinatra-Contrib 見てみました。個人的には何するにしても reloader と json が必須なので Sinatra 使う時には必ずセットで入れてたライブラリなんですが、こう見るとなかなか味のあるツールセットでした。不明を恥じるばかりです。

multi_routenamespaceは超いいしcontent_forcaptureはテンプレートの書き方をずいぶん楽にしてくれそう。少し大きくなってきたときに Extention で分離するのはスマートなガイドラインだと思う。