rack,貌似已經把rails改革了。
rack是什麼?rack提供了用ruby開發web應用的乙個介面。比如rails框架,就是由rack承擔著跟web伺服器之間的互動。簡而言之,rack已經成為ruby開發web應用程式的乙個規範,它統一了web伺服器和web框架之間的互動介面。它所支援的web伺服器和web框架已經非常之多: 。
rack的規範非常簡單,就是乙個call方法:spec.html 。接受乙個environment,然後返回status,header和body。這不就是http的全部麼?
為什麼不可以在rack和web framework之間做些事情呢?於是rack middleware發展起來了。rack中介軟體其實就是一些遵循rack規範的應用。為什麼要發展出rack middleware?因為很多事情在這裡做起來就非常方便,其實就是aop的方式(你也可以把它理解成filter)。
看一下眾多的middlewares: 。或者在你的最新(2.3)rails應用下敲下命令列:rake middleware。
endmiddleware,正不就是做這些事情的好地方麼?
又比如,某人開發的google_analytic middleware:
def call env
body = ""
response.each
index = body.rindex("")
if index
body.insert(index, tracking_code(options[:web_property_id]))
headers["content-length"] = body.length.to_s
response = [body]
endend
[status, headers, response]
end
請再次用rake middleware看看清楚。
use rack::lock
use actioncontroller::failsafe
use actioncontroller::session::cookiestore, #use rails::rack::metal
use actioncontroller::paramsparser
use rack::methodoverride
use rack::head
use actioncontroller::stringcoercion
use activerecord::connectionadapters::connectionmanagement
use activerecord::querycache
run actioncontroller::dispatcher.new
沒錯,在rails2.3之後,所有的東西都變成middleware了,包括action controller stack本身。
rails應用的呼叫就是對middleware堆疊的呼叫。從最初始的rack::lock:
def call(env)
old, env[flag] = env[flag], false
ensure
env[flag] = old
end
到最後的actioncontroller::dispacher.new:
def call(env)
if @@cache_classes
else
reloader.run do
# when class reloading is turned on, we will want to rebuild the
# middleware stack every time we process a request. if we don't
# rebuild the middleware stack, then the stack may contain references
# to old classes metal classes, which will b0rk class reloading.
build_middleware_stack
endend
end
def build_middleware_stack
end
_call(env)到底做了什麼,還是看個究竟吧:
def _call(env)
@env = env
dispatch
enddef dispatch
begin
run_callbacks :before_dispatch
routing::routes.call(@env)
rescue exception => exception
controller.call_with_exception(@env, exception).to_a
else
raise exception
endensure
run_callbacks :after_dispatch, :enumerator => :reverse_each
endend
你沒發現,大部分主要物件都實現了call(env)介面麼?
def call(env)
return result unless @pass_through_on.include?(result[0].to_i)
endend
關於更多的知識,請見: 。在這裡會看到script/server的實現,如何定製rackup,如何定製middleware,如何生成metal等。
eofps:
技術總是翻天覆地地變化著,rails2.3又有了很多不同。做乙個it民工還真是他媽的累,不過如果可以苦中作樂,倒也認了。每週一題越來越名不副實了,不過還是繼續學習,繼續寫吧。
hihoCoder每週一題
時間限制 10000ms 單點時限 1000ms include include include include includeusing namespace std int n,m define max 26 struct trie trie void createtrie char str el...
每週一題(1)
把2019分解成3個各不相同的正整數之和,並且要求每個正整數都不包含數字2和4.一共有多少種不同的分割方法。注意交換3個整數的順序被視為同一種方法1,例如1000 1001 18和1001 1000 18被視為同一種。這是一道結果填空的題,你只需要算出結果後提交即可。本題的結果為乙個整數,在提交答案...
每週一題 4
如圖p1.png所示的螺旋折線經過平面上所有整點恰好一次。對於整點 x,y 我們定義它到原點的距離dis x,y 是從原點到 x,y 的螺旋折線段的長度。例如dis 0,1 3,dis 2,1 9 給出整點座標 x,y 你能計算出dis x,y 嗎?輸入格式 x和y對於40 的資料,1000 x,y...