ruby - plusieurs - variable locale et globale java




Une variable globale définie à l'intérieur d'une route Sinatra est-elle partagée entre les demandes? (2)

Dire que j'ai:

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

Si j'ai des milliers de requêtes par seconde arrivant à /, le $ random sera-t-il partagé et 'fuira' hors du contexte ou va-t-il agir comme une variable 'locale' au bloc get?

J'imagine que s'il était défini en dehors du contexte de get '/' do il serait effectivement partagé mais je me demande s'il y a un mécanicien à $ en ruby ​​dont je ne suis pas au courant.


En dehors de certaines exceptions très spécifiques (telles que les globales associées à une expression régulière), un global est partagé avec tout le processus - il n'y a pas de portée.


Cette partie de Sinatra README sur la portée est toujours utile à lire mais si vous avez seulement besoin que la variable persiste pour la requête alors je pense qu'il y a 3 façons principales que je suggérerais de faire, et la clé est vraiment un filtre

Un bloc avant

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 sera hors de portée à la fin de la requête et sera réinitialisé au début de la suivante. Il sera accessible par n'importe quel itinéraire, donc si par exemple vous avez utilisé pass pour le transmettre à un autre itinéraire qui serait le seul moment où les autres blocs pourraient voir ce qui avait été défini par le bloc de route précédent.

Utilisation de l'assistant de paramétrage

set :mylog, []

Puis, comme ci-dessus, remplacez @my_log avec settings.my_log . Si le bloc @my_log n'est pas réinitialisé, le contenu de @my_log sera conservé dans les requêtes.

Utilisation de l'assistant de réglages avec quelque chose comme 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

Maintenant, l'instance redis est disponible via settings.redis . Pas besoin de s'inquiéter de la portée variable (j'utiliserais les locaux avec ça), il suffit de pousser directement sur Redis. Vous obtenez le meilleur des deux mondes, mais si vous voulez, vous pouvez faire:

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






sinatra