私が持っていると言う:
get '/' do
$random = Random.rand()
response.body = $random
end
/に毎秒数千のリクエストが来る場合、$ randomは共有され、コンテキスト外で「リーク」しますか、それともgetブロックに対して「ローカル」変数のように機能しますか?
それが文脈の外で定義されたとしたら、get '/' doそれは確かに共有されるだろうと思いますが、私が知らないルビーの$のメカニズムがあるのではないかと思います。
スコープに関するSinatraREADMEのこの部分は、常に読むのに役立ちますが、要求に対して永続化する変数のみが必要な場合は、これについて行うことをお勧めする3つの主な方法があると思います。実際、重要なのはフィルターです。
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ますsettings.my_log。beforeブロックを再初期化しないと、の内容は@my_logリクエスト間で永続化されます。
# 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
これで、redisインスタンスはを介して利用できますsettings.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
いくつかの非常に特殊な例外(正規表現の一致に関連するグローバルなど)を除いて、グローバルはプロセス内のすべてのものと共有されます-スコープはありません。