はじめに
最近まで 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_route
とnamespace
は超いいしcontent_for
とcapture
はテンプレートの書き方をずいぶん楽にしてくれそう。少し大きくなってきたときに Extention
で分離するのはスマートなガイドラインだと思う。