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

标签 ruby routing sinatra

假设我有:

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/

相关文章:

网址上的 AngularJS "#!"

ruby - 如何从 Sinatra 中删除路由?

ruby - 使用 Datamapper 在 Sinatra 中选择、复选框和单选按钮元素

Ruby 检查与 Rspec 中的 to_s

ruby-on-rails - Flash 消息的 CSS 样式

ruby - rails 3 中的 Rufus 调度器实现

css - 外部 CSS 文件不能与 bootstrap 一起工作

ruby - 如何在任何 Web 服务器(Apache 或 Mongrel 或其他任何东西)中运行简单的 ruby​​ 脚本

rest - Symfony2 : simplest way to get RESTful urls

ruby - 条件逻辑在 haml 中不起作用