Rackのポインタ集


# モチベーション
Rackの勉強途中です。
一段落つかないので、現状把握しているポインタをまとめます。

# 文献情報
## 本家
http://rack.github.io/
ご本尊

### 仕様
http://www.rubydoc.info/github/rack/rack/file/SPEC
Rack Spec。Rackの仕様といえばこれです。

### 実装
https://github.com/rack/rack/blob/master/lib/rack.rb
実装、ソースコードはこの辺から読めるます。

基本的にはRequest, Response, Builderの３つを読めば、大体十分だと思います。

- [Rack::Request](https://github.com/rack/rack/blob/master/lib/rack/request.rb)
- [Rack::Response](https://github.com/rack/rack/blob/master/lib/rack/response.rb)
- [Rack::Builder](https://github.com/rack/rack/blob/master/lib/rack/builder.rb)

Rack::Requestしか読んでいませんが、特に黒魔術はなく、わりとベタに書いてあります。

## 英語情報
### Rack Bootcamp

http://rack-bootcamp.slashdeploy.com/

5$で19ページのPDFです。技術同人誌だと思えば、妥当な価格感です。
後述の **Rack from the Beginning** の加筆版。 **Rack from the Beginning** は無料で読めます。
2016/10に更新されています。最近の情報に追従している安心感があります。

**Rack from the Beginning**から増えている章は

- Testing
- Servers

です。各章もノリがbootcampっぽくなっていて、サンプルコードなどが修正されているようです。

試していませんが、動かなさそうなサンプルコードも見受けられます。

- P6 `require.body`は`request.body`の間違い？
- P8 無限ループになりそう

### Rack from the Beginning
http://hawkins.io/2012/07/rack_from_the_beginning/
無料で読めます。よくまとまっていてわかりやすいです。

冒頭に

> This post is out of date and contains some technical errors.

と「技術的な間違いがある」とエクスキューズされています。
どの部分のことかはわかりませんでした。
#### 章立て

1. **Dead Simple Rack Applications**: Rack アプリケーションのHello World
1. **Env**: Rack Specの話。入力情報をすべてenv変数っていうハッシュで受け取る
1. **Abstractions**: Rack実装の話（１）。envの操作や、レスポンス作成のためにRack::RequestやRack::Responseというクラスがある
1. **Middleware**: Rack実装の話（２）。ミドルウェアという仕組みで、複数のモジュールを組み合わせれる
1. **Composing Rack Apps from Middleware**: Rack実装の話（３）。Rack::Builderを使ってミドルウェアを組み合わせる
1. **Rackup**: Rack実装の話（４）。rackupコマンドを使うとconfig.ruにRack::Builderの設定が書ける
1. **Rails & Rack**: RailsもRackミドルウェアを組み合わせて使っている

## 日本語情報
### Rack解説 - Rackの構造とRack DSL
http://qiita.com/higuma/items/838f4f58bc4a0645950a
割とわかりやすい。
Rack実装を構成するパーツの説明がないので、 **Rack from the Beginning** で補うと良さそうです。
用語の定義に出典がないので、オレオレ用語なのか、一部コミュニティでの方言なのか、公式の用語なのか判別できない点はつらいです。本家に当たりましょう。
後半になると、RailsにひきずられてRailsの話なのか、Rackの話なのか判別できなくなってくるのが辛いです。

全体として含まれているリンクが素晴らしいと思います。
Rackのインターフェース（call）がProcに合わせている話が載っているのが良かったです。

### Ruby Freaks Lounge
現存するおそらく唯一の編集者の入った日本語文章。
2009年と少し古いので、情報の鮮度に不安が残ります。
最初に読むのには向かないと思います。

- [第23回　Rackとは何か（1）Rackの生まれた背景](http://gihyo.jp/dev/serial/01/ruby/0023)
- [第24回　Rackとは何か（2）Rackの使い方](http://gihyo.jp/dev/serial/01/ruby/0024)
- [第25回　Rackとは何か（3）ミドルウェアのすすめ](http://gihyo.jp/dev/serial/01/ruby/0025)

またRackの仕様と実装の詳細は載っていません。
**Rack from the Beginning** で補うと良いと思います。

WSGIやPEP333などの歴史的な話が載っているのが面白いです。


### WSGI / Rack / PSGI てなんぞ
https://www.slideshare.net/katsuji/wsgi-rack-psgi
WSGIとかの歴史の話がもう少し詳しく載っています。

### Rackとは何か
http://qiita.com/k0kubun/items/248395f68164b52aec4a
あまりちゃんと読んでいません。
RackのAPIから掘っていく感じでしょうか？


## Rackミドルウェアの使用例
### Rails と Rack | Rails ガイド
https://railsguides.jp/rails_on_rack.html
RailsでRackミドルウェアをどう使っているかの説明があります。

### 標準ミドルウェア
https://github.com/rack/rack#available-middleware
に抜粋されています。

> Available middleware
>
> Between the server and the framework, Rack can be customized to your applications needs using middleware, for example:
>
> Rack::URLMap, to route to multiple applications inside the same process.
> 
> Rack::CommonLogger, for creating Apache-style logfiles.
> 
> Rack::ShowException, for catching unhandled exceptions and presenting them in a nice and helpful way with clickable backtrace.
> 
> Rack::File, for serving static files.
>
> …many others!

実装は
https://github.com/rack/rack/tree/master/lib/rack
にあります。
自分でミドルウェアを書くときの参考になりそうです。

## その他
### 次世代の Rack や WSGI を考えてみる
http://qiita.com/kwatch/items/67657fef43666479bb99
現状のRack仕様の問題点と改善案が描いてあります。
これが面白く読めるようになれば、Rackの知識はかなり身についたと言えそうです。

# 実装
読み途中

[Rack::Request::Env](https://github.com/rack/rack/blob/master/lib/rack/request.rb#L34)をクラス内で定義して、[最後にinclude](https://github.com/rack/rack/blob/master/lib/rack/request.rb#L484)している。
Rubyでは、クラス内にmodlue作って、巨大クラス内でスコープを分けれるらしい。

initializeの呼ばれる順序が謎.
[Rack::Request#initialize](https://github.com/rack/rack/blob/master/lib/rack/request.rb#L16)の`super`は[Rack::Request::Env#initialize](https://github.com/rack/rack/blob/master/lib/rack/request.rb#L38)を呼びますよね？
その後、この中の`super`は何を呼ぶのだろうか？`Object#initialize`？

# 個人的によくわかっていない点

- rackの起動時のオプション
- ミドルウェアの書き方
- rackそのものの実装
- callがクラスメソッドでもいいのは、Procオブジェクトやlambdaオブジェクトを受け取るためな気がする。本当かな？
- Rack::Builder#useってなんでこういう風に呼べるんだっけ？Rubyのどういう文法を使っているのか？ブロック内のselfはメソッドから見るselfと一緒なんだっけ？

```
app = Rack::Builder.new do
  use Rack::Etag # Add an ETag
  use Rack::ConditionalGet # Support Caching use Rack::Deflator # GZip
  run HelloWorldApp # Say Hello
end
```

- Rack::Builderはビルダーパターンという意味の名前ぽい。[GoFの実装](http://qiita.com/disc99/items/840cf9936687f97a482b)とだいぶ違ってもにょもにょする。現代では **コンストラクタの代わりに使えるDSLを作ることをビルダーパターンと言う** のかな？
- Rack::Builderは、なんでブロックを受け取るのだろう？ミドルウェアの順番を指定するだけなら、配列もらってくれば十分