ruby - son - ¿Se define una variable global dentro de una ruta de Sinatra compartida entre solicitudes?
variables globales y locales en visual basic (2)
Digamos que tengo:
get ''/'' do
$random = Random.rand()
response.body = $random
end
Si tengo miles de solicitudes por segundo que llegan a /, ¿se compartirán los $ aleatorios y la "fuga" fuera del contexto o se comportará como una variable "local" para el bloque get?
Me imagino que si se definió fuera del contexto de get ''/'' do
sería de hecho compartido, pero me pregunto si hay una mecánica para $ en ruby de la que no tengo conocimiento.
Aparte de algunas excepciones muy específicas (como la coincidencia de expresiones regulares relacionadas con globales), un elemento global se comparte con todo en el proceso; no hay un alcance.
Esta parte del LEADRE de Sinatra sobre el alcance siempre es útil para leer, pero si solo necesita la variable para persistir en la solicitud, entonces creo que hay 3 formas principales que sugiero al respecto, y realmente la clave es un filtro
Un bloque anterior
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
saldrá del alcance al final de la solicitud y se reinicializará al comienzo de la próxima. Será accesible por cualquier ruta, de modo que si, por ejemplo, usaste el pass
para pasarlo a otra ruta, ese sería el único momento en que los otros bloques podrían ver lo que había sido establecido por el bloque de ruta anterior.
Usando la configuración helper
set :mylog, []
Luego, igual que arriba, simplemente reemplace @my_log
con settings.my_log
. Sin el bloque before
reiniciarlo, el contenido de @my_log
mantendría en todas las solicitudes.
Usando el asistente de configuración con algo como 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
Ahora la instancia de redis está disponible a través de settings.redis
. No hay necesidad de preocuparse por el alcance variable (yo usaría los locales con él), simplemente presione directamente a Redis. Obtienes lo mejor de ambos mundos, pero si quieres, puedes:
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