是在请求之间共享的Sinatra路由中定义的全局变量吗?

说我有:

get '/' do $random = Random.rand() response.body = $random end 

如果我每秒有数千个请求进入/,$ random会在上下文之外共享和“泄漏”,还是会像get块的’local’变量一样?

我想如果它是在get '/' do的上下文之外定义它确实会被共享,但我想知道是否有一个我不知道的ruby中的机制。

关于范围的Sinatra自述文件的这一部分总是有助于阅读,但如果你只需要变量来保持请求,那么我认为有三种主要方式我建议去做这个,真的关键是filter

前块

 before do @my_log = [] end get "/" do @my_log < < "hello" @my_log << "world" @my_log.inspect end get "/something-else" do @my_log << "is visible here too" end # => output is ["hello", "world"] 

@my_log将在请求结束时超出范围,并在下一个开始时重新初始化。 任何路由都可以访问它,因此,例如,如果您使用pass将其传递给另一个路径,那么其他路径将是唯一一次可以看到先前路由块已设置的路径。

使用设置助手

 set :mylog, [] 

然后与上面相同,只需将@my_log替换为@my_log 。 如果没有before block重新初始化,那么@my_log的内容将在请求之间保持@my_log

使用Redis等设置助手

 # I always do this within a config block as then it's only initialised once config do uri = URI.parse(ENV["URL_TO_REDIS"]) set :redis, Redis.new(:host => uri.host, :port => uri.port, :password => uri.password) end 

现在可以通过settings.redis获得redis实例。 无需担心变量范围(我会使用本地人),只需直接推送到Redis。 那么你可以获得两全其美,但如果你想要,你可以做到:

 before do @my_log = [] end get "/" do @my_log < < "hello" @my_log << "world" "Hello, World" end after do settings.redis.set "some_key", @my_log settings.redis.expire "some_key", 600 # or whatever end 

除了一些非常具体的exception(例如正则表达式匹配相关的全局变量)之外,全局与流程中的所有内容共享 – 没有范围界定。