0

I'm thinking about global variables in my rails application. I've searched the net about that, and found it (of course) flagged as a bad practice. I already knew that.

But I have not found another way than a global variable for what I need. Can an experienced Rails programmer help me ?

What I want to do is to create a new dedicated logger, for example logging to "log/audit.txt" and share it between several controllers. Of course, I would rather not have to recreate this "logger" object for every request.

For now, I create a logger in a global variable $my_logger in an initializer, and use it across my controllers.

What do you think ? Is there a better way to do that ?

Thank you.

3 Answers 3

2

The general OO stance against using global variables and singletons of any type -- in Rails and in all other OO habitats -- is to avoid the "slippery slope" towards not doing OO design at all. Global variables are to be avoided as much as possible, but your logger is obviously a case where a Singleton of some sort makes sense. The Rails environment is an example: you only have on Rails environment per application, and it's essentially a Singleton. Or consider Notifier.deliver...

Don't worry about where to put it if it must be global. Make a Singleton object with class methods as accessors and put it in lib or anywhere you think is appropriate (making a plugin might also be appropriate, for instance). Then you just use Logger.instance.log whatever. Of course you'll have to put in safeguards to make sure that the thing gets instantiated only once.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, this is the solution I took eventually. The "include Singleton" of Ruby made it a breeze.
Thanks, yeah, Singleton gets a bad rap, but in certain cases he's the man for the job.
1

This SO question is extremely relevant: In Ruby on Rails how can I persist objects in memory between sessions

If you use the accepted answer, you'll be able to keep the logger in memory in production mode across requests.

However, I like the second answer... to quote:

I wouldn't worry too much about loading and discarding objects unless you can come up with a benchmark that proves it's an issue. Each request creates an extraordinary amount of intermediate objects as a matter of course, and these are generally created and destroyed in a matter of several milliseconds.

...

Benchmark first, optimize only when required.

3 Comments

OP's not worried about loading and discarding objects. OP is worried about opening and closing files every time he/she wants to write to a log.
@Yar: not sure how you drew that conclusion. OP said "I would rather not have to recreate this "logger" object for every request."
Thank you for this interesting link, complementing my analyzis.
0

Create your own custom logger class and require it when applicable.

Example here:

http://ianma.wordpress.com/2009/04/08/custom-logging-in-ruby-on-rails/

2 Comments

Thank you. This method means that the logger will be re-created for every request. That's what I want to avoid.
Except of course if, like in your example, you include it in the environment.rb. But then it becomes a global variable/constant. Back to start...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.