こんにちは。サイオステクノロジー技術部武井です。
Azure App Service上でRubyを動かすことはまだできないみたいですが、できたらいいなという思いを込めて、今回は、RubyのWebアプリケーションフレームワークSinatraのソースをざっくり解析してみました。
SinatraはRubyでWebアプリケーションを作成することができる軽量フレームワークです。フレームワークではなくDSLだという意見もあるようです。
ただし、あまり情報がなく、フレームワークがどういう動きをしているのかは、やはりソースをみるしかないなと思ったので、せっかくのOSSなので、ソース見てみました。
※勘違いしていることろがあるかもしれませんが、そこはご容赦下さい(..)_
以下のようなソースコードがあるとします。よくあるこんにちは世界です。
require 'sinatra' get '/' do "Hello world " end
このアプリケーションの動きを私なりに解析してみました。ざっくりですが。
まず、1行目のrequire ‘sinatra’でsinatra.rbが呼ばれて、その中でさらにsinatra/main.rbが呼ばれてました。
sinatra/main.rbは以下のようなソースでした。
■main.rb
require 'sinatra/base' module Sinatra class Application < Base ・・・(中略)・・・ at_exit { Application.run! if $!.nil? && Application.run? } end extend Sinatra::Delegator
at_exit〜で呼ばれているのは、継承元Baseクラスのrunメソッドで、実態はApplicationというクラス自身のインスタンスを引数にして、Rack Handlerをコールしてました。なので、ApplicationクラスはRackアプリケーションということになるとおもいます。
extend Sinatra::Delegatorはgetやpostなどを定義しているモジュールでTopでextendしていることによって、どこからでも呼び出せるようにしているのだと思います、たぶん。
getのblock引数に登録したものはApplicationクラスの@rotuesというインスタンス変数に格納されているようで、リクエストがあるごとに参照しているようです。
話はもどりますが、mian.rbのat_exitでApplicaton.runを登録したことによって、Applicationクラスのcallメソッドがcallback関数として登録されて、リクエストがあるたびに呼び出されるはずです。
Applicationクラスの基底クラスのBaseクラスが定義してあるbase.rbは以下のとおりでした。
■base.rb
・・・(中略)・・・ class Base def call(env) dup.call!(env) end ・・・(中略)・・・
リクエストがあるたびに、Applicationクラスのインスタンスを複製していて、複製したインスタンスのcall!メソッドを読んでいました。
そしてcall!メソッドでは、RackのRequest.newやResponse.newでHTTPリクエストを受け取ったり、HTTPレスポンスを生成したりしてるみたいです。
そんなゆる〜い感じでSinatraを解析してみました。なんか間違っていたらすみません・・・(..)_