假设我有:
get '/' do
$random = Random.rand()
response.body = $random
end
如果我每秒有数千个请求到达/,$random 是否会被共享并“泄漏”到上下文之外,或者它会像 get block 的“本地”变量一样?
我想如果它是在 get '/' do
的上下文之外定义的,它确实会被共享,但我想知道在 ruby 中是否有我不知道的 $ 机制。
最佳答案
This part of the Sinatra README about scope is always helpful to read但是,如果您只需要为请求保留变量,那么我认为我建议使用 3 种主要方法来解决这个问题,而真正的关键是 filter
block 前A
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
将其传递到另一条路由,那将是其他 block 唯一可以看到先前路由 block 设置的内容的时间。
使用设置助手
set :mylog, []
然后同上,将@my_log
替换为settings.my_log
即可。如果没有 before
block 重新初始化它,那么 @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
关于ruby - Sinatra 路由中定义的全局变量是否在请求之间共享?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14388263/