2

私はSinatraでクイックヘルパーを作成していました。ここで、パスが存在する場合はそれによって提供されるパス、またはデフォルトredirect_to_nextのパスにリダイレクトします。session[:next]

Sinatraでは、session実際にはRackによって提供され、仕様によって、のインターフェイスのようなハッシュを提供すると言われていますfetch。私は自分の問題を説明するために次のエラーヘルパーを書きました。

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

ログインしていないときに/settingsにアクセスしようとすると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)
4

1 に答える 1

3

セッションハッシュは通常のRubyHashではなく、Rack::Session::Abstract::SessionHashです。SessionHash実際にはから継承しHashますが、メソッド とメソッドをオーバーライドし、キーを保存および取得する前に任意のキーを呼び出し[]=[]to_sます。

更新例の拡張:

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と、メソッドは文字列に変換されずに親ハッシュに直接ディスパッチされるため、一致するキーが見つかりません。

したがって、セッションでは常に文字列をキーとして使用すれば、すべてが機能するはずです。

于 2012-04-29T22:01:21.040 に答える