Global (accessible anywhere), but per-request variable

Is there any way to create a variable (or something) that’s global in
the sense that it can be accessed from any method of any class withoug
having to be passed around, but that’s not shared between requests?
$variables are shared, classes and their class-level properties are
shared if config.cache_classes = true (which looks like a nice trap to
me since the cache_classes is false in development and test environments
and I did not find any information, much less a warning, regarding the
different behaviour of class-level properties. I can easily imagine
someone using some class-level properties, testing their stuff and then
get misterious errors on prod.)

Or … some way from a class method to store&access some request
specific data behind the scenes?

This is for a debug tool, something similar to the Logger, but it needs
to keep the level and other stuff different for different requests.

Thanks, Jenda

El Apr 13, 2007, a las 3:06 PM, Jenda K.
escribió:

Is there any way to create a variable (or something) that’s global in
the sense that it can be accessed from any method of any class withoug
having to be passed around, but that’s not shared between requests?

If I understand it correctly it would be enough to initialize
something global like a singleton, $global, whatever, with a filter
in ApplicationController. If you need it outside the web app, e.g. in
the console, it could have some default set in environment.rb.

– fxn

Xavier N. wrote:

El Apr 13, 2007, a las 3:06 PM, Jenda K.
escribi�:
Is there any way to create a variable (or something) that’s global in

the sense that it can be accessed from any method of any class withoug
having to be passed around, but that’s not shared between requests?

If I understand it correctly it would be enough to initialize
something global like a singleton, $global, whatever, with a filter
in ApplicationController. If you need it outside the web app, e.g. in
the console, it could have some default set in environment.rb.

– fxn

Hola fxn,

No, I don’t need it outside the web app.

And I don’t think initializing a $global would work. What if two
requests come at about the same time? Request A inicializes the $global,
request B inicialized the $global, and then requst A used the $global
using the level and other settings set by request B? No thanks!

I know I can use a before:filter to get a snippet of code ran at the
start of the request processing, what I don’t know is where to store the
stuff then so that it’s global as “accessible from anywhere” but
request-specific.

Gracias, Jenda

Hi Jenda,

And I don’t think initializing a $global would work. What if two
requests come at about the same time? Request A inicializes the $global,
request B inicialized the $global, and then requst A used the $global
using the level and other settings set by request B? No thanks!

I don’t think that’s going to be a problem.

Your web server might be able to process multiple requests
simultaneously, but that’s probably because it’s got multiple
dispatch.fcgi processes running. But each of those processes runs in
a strictly serial fashion. Rails doesn’t somehow start processing the
next request while the previous one is still finishing, so don’t worry
about that.

I know I can use a before:filter to get a snippet of code ran at the
start of the request processing, what I don’t know is where to store the
stuff then so that it’s global as “accessible from anywhere” but
request-specific.

Any module or class that’s loaded is available throughout all your
models, views and controllers etc., so if you set a class variable on
a module or class it will be available anywhere; you can then clean it
up in an after-filter so it doesn’t persist into the next request.

Regards,
Dave

Singletons are the best way to handle this.

It is easily implemented in Ruby:

require ‘singleton’
class Single
include Singleton
end

(Singleton is a standard Module).

Single.instance() gives you the one and only instance present in your
app. If none is present, you get a new one.

Greetings
Skade

El Apr 13, 2007, a las 3:33 PM, Jenda K.
escribió:

And I don’t think initializing a $global would work. What if two
requests come at about the same time? Request A inicializes the
$global,
request B inicialized the $global, and then requst A used the $global
using the level and other settings set by request B? No thanks!

Yeah, the assumption you miss is that Rails is single-thread multi-
process. Two dynamic requests cannot be served at the same time by
the same Ruby interpreter.

– fxn

Xavier N. wrote:

El Apr 13, 2007, a las 3:33 PM, Jenda K.
escribi�:
And I don’t think initializing a $global would work. What if two

requests come at about the same time? Request A inicializes the
$global,
request B inicialized the $global, and then requst A used the $global
using the level and other settings set by request B? No thanks!

Yeah, the assumption you miss is that Rails is single-thread multi-
process. Two dynamic requests cannot be served at the same time by
the same Ruby interpreter.

– fxn

The question is whether it’s a safe asumption for the future. Though I
guess there is that much code that assumes this that it doesn’t matter
if my debug class does as well.

Thanks, Jenda