【问题标题】:Sinatra/Rack session.fetch producing unexpected resultsSinatra/Rack session.fetch 产生意想不到的结果
【发布时间】:2012-04-29 20:18:57
【问题描述】:

我在 Sinatra 中为 redirect_to_next 编写了一个快速助手,我在其中重定向到 session[:next] 提供的路径(如果存在或默认路径)。

在 Sinatra 中,session 真正由 Rack 提供,而 spec 据说为 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)

【问题讨论】:

  • 我无法在此处重现该问题。您是否可以提供一个显示此行为的最小但完整的示例?

标签: ruby sinatra rack


【解决方案1】:

会话哈希不是普通的 Ruby 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 时,传递一个符号,该方法会直接分派到父哈希,而不是转换为字符串,因此找不到匹配的键。

因此,请始终在会话中使用字符串作为键,一切都应该正常工作。

【讨论】:

    猜你喜欢
    • 2021-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-20
    • 2011-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多