Rails每週一題 二十 Rack變革

2021-08-30 07:58:53 字數 4221 閱讀 4387

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...