Sinatra-Contribまとめ


# はじめに

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

# Contribの中身を知る

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

- https://github.com/sinatra/sinatra/tree/master/sinatra-contrib (本体に統合されています。[古いリポジトリはこちら
](https://github.com/sinatra/sinatra-contrib))

## sinatra/capture

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

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

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

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

## sinatra/config_file

- http://www.sinatrarb.com/contrib/config_file.html

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

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

- http://www.sinatrarb.com/contrib/content_for.html

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

## sinatra/cookies

- http://www.sinatrarb.com/contrib/cookies.html

> Easy way to deal with cookies

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

## sinatra/engine_tracking

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

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

## sinatra/json

- http://www.sinatrarb.com/contrib/json.html

よく使うやつ。

```
def "/" do
  json :name => "akita" 
end
```

## sinatra/link_header

- http://www.sinatrarb.com/contrib/link_header.html

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

## sinatra/multi_route

- http://www.sinatrarb.com/contrib/multi_route.html

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

```
get '/foo', '/bar' do

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


## sinatra/namespace

- http://www.sinatrarb.com/contrib/namespace.html

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

- http://www.sinatrarb.com/contrib/respond_with.html

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

- http://www.sinatrarb.com/contrib/decompile.html

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

```
      # 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

- http://www.sinatrarb.com/contrib/reloader.html


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

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

## sinatra/extension 

- http://www.sinatrarb.com/contrib/extension.html

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

## sinatra/streaming

- http://www.sinatrarb.com/contrib/streaming.html

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 で使われている。これは本当にヘルパーだからコード読んで使えそうなら使う感じだろうなー。

- http://www.slideshare.net/udzura/testing-in-sinatra

## 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` で分離するのはスマートなガイドラインだと思う。