2012-04-29 82 views
2

我在Sinatra爲redirect_to_next寫了一個快速幫手,其中我重定向到session[:next]提供的路徑(如果存在的話)或默認值。Sinatra/Rack session.fetch產生意想不到的結果

在Sinatra中,session實際上由Rack提供,並且由spec據說爲fetch提供類似散列的接口。我寫了下面的錯誤幫助來解釋我的問題。

error 401 do 
    session[:next] = request.path 
    puts "get #{session[:next]}" 
    puts "fetch #{session.fetch(:next, '/')}" 
    redirect "/login" 
end 

當我試圖訪問/設置當沒有登錄,我halt 401它運行上述代碼。這是它打印到我的終端:

get /settings 
fetch/

:next存在的關鍵,那麼,爲什麼給我默認的,如果它不?

更新

這個小例子,顯示了相同的行爲。

require 'sinatra' 

set :sessions, true 

get '/' do 
    session[:testing] = "hello" 
    puts "get #{session[:testing]}" 
    puts "fetch #{session.fetch(:testing, 'goodbye')}" 
end 

日誌

[2012-04-29 14:11:51] INFO WEBrick::HTTPServer#start: pid=1954 port=9292 
get hello 
fetch goodbye 
10.0.2.2 - - [29/Apr/2012 14:11:54] "GET/HTTP/1.1" 200 - 0.0485 

軟件

  • 紅寶石(1.9.3p194)
  • 機架(1.4.1)
  • 屈(1.3.2)
+0

我不能在這裏重現問題。您是否可以提供一個顯示此行爲的最小但完整的示例? –

回答

3

會話散列不是普通的紅寶石Hash,它是Rack::Session::Abstract::SessionHashSessionHash實際上是從Hash繼承,但它是overrides the []= and [] methods, calling to_s on any keys before storing and retrieving them

擴展您的更新例如:

require 'sinatra' 

set :sessions, true 

get '/' do 
    session[:testing] = "hello" 
    puts "get    #{session[:testing]}" 
    puts "fetch    #{session.fetch(:testing, 'goodbye')}" 
    puts "fetch with string #{session.fetch(:testing.to_s, 'goodbye')}" 
end 

給出了這樣的輸出:

get    hello 
fetch    goodbye 
fetch with string hello 

當您使用Hash#fetch,路過一個符號,該方法被直接發送給父散,沒有轉換成一個字符串,所以找不到匹配鍵。

因此,總是在您的會話中使用字符串作爲鍵,一切都應該工作。

+0

謝謝。這也適用於我的主要項目。 –

相關問題