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.

Offirmo
  • 18,962
  • 12
  • 76
  • 97

3 Answers3

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.

Dan Rosenstark
  • 68,471
  • 58
  • 283
  • 421
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.

Community
  • 1
  • 1
Jesse Wolgamott
  • 40,197
  • 4
  • 83
  • 109
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/

hade
  • 1,715
  • 1
  • 16
  • 24
  • Thank you. This method means that the logger will be re-created for every request. That's what I want to avoid. – Offirmo Jan 24 '11 at 13:12
  • 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... – Offirmo Jan 25 '11 at 17:28