モチベーション
Rackの勉強途中です。
一段落つかないので、現状把握しているポインタをまとめます。
文献情報
本家
仕様
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の3つを読めば、大体十分だと思います。
Rack::Requestしか読んでいませんが、特に黒魔術はなく、わりとベタに書いてあります。
英語情報
Rack Bootcamp
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.
と「技術的な間違いがある」とエクスキューズされています。
どの部分のことかはわかりませんでした。
章立て
- Dead Simple Rack Applications: Rack アプリケーションのHello World
- Env: Rack Specの話。入力情報をすべてenv変数っていうハッシュで受け取る
- Abstractions: Rack実装の話(1)。envの操作や、レスポンス作成のためにRack::RequestやRack::Responseというクラスがある
- Middleware: Rack実装の話(2)。ミドルウェアという仕組みで、複数のモジュールを組み合わせれる
- Composing Rack Apps from Middleware: Rack実装の話(3)。Rack::Builderを使ってミドルウェアを組み合わせる
- Rackup: Rack実装の話(4)。rackupコマンドを使うとconfig.ruにRack::Builderの設定が書ける
- 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年と少し古いので、情報の鮮度に不安が残ります。
最初に読むのには向かないと思います。
また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をクラス内で定義して、最後にincludeしている。
Rubyでは、クラス内にmodlue作って、巨大クラス内でスコープを分けれるらしい。
initializeの呼ばれる順序が謎.
Rack::Request#initializeのsuper
はRack::Request::Env#initializeを呼びますよね?
その後、この中の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の実装とだいぶ違ってもにょもにょする。現代では コンストラクタの代わりに使えるDSLを作ることをビルダーパターンと言う のかな?
- Rack::Builderは、なんでブロックを受け取るのだろう?ミドルウェアの順番を指定するだけなら、配列もらってくれば十分