HiveBrain v1.2.0
Get Started
← Back to all entries
patternrubyrailsMinor

Storing a Ruby app's settings

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
settingsstoringappruby

Problem

I have used code which looks a little like this in an app I'm working on:

module App
  module Settings

    class << self
      attr_accessor :console, :file
    end

    self.console ||= true
    self.file    ||= []

  end
end


I decided to use this method because I like the interface, I had the idea after reading the Singleton examples from Design Patterns in Ruby.

I can then require 'app/settings' from any file in my app and read/write the settings

p App::Settings.console
App::Settings.file << "afile.rb"
p App::Settings.file


etc...

Is this a reasonable way to keep my settings in a single file? I feel I am unnecessarily repeating myself. Any ideas for DRYing?

Solution

There is nothing really wrong with this but using a simple hash may be easier:

module App
    @@settings = {
        :console => true,
        :file => []
    }
    def self.settings
        @@settings
    end
end


Your following code would then become:

p App.settings[:console]
App.settings[:file] << "afile.rb"
p App.settings[:file]


There are several advantages to this approach:

-
Hashes are easy to serialise and store in files using yaml/json/etc.

require 'yaml'
p App.settings.to_yaml


-
You can reference App.settings in a local variable to avoid writing it out:

s = App.settings
#do stuff with s


-
Hash has many convenience methods for iterating over its values.

App.settings.each do |key, value|
    #do something
end


-
You can add to/update it succinctly using the merge! method.

App.settings.merge! :console => false, :newsetting => 'value', :etc => '...'


To get functionality like this in your method would require you to write lots of methods yourself. It's better to just use the built in functionality that Ruby has instead of reinventing the wheel.

Code Snippets

module App
    @@settings = {
        :console => true,
        :file => []
    }
    def self.settings
        @@settings
    end
end
p App.settings[:console]
App.settings[:file] << "afile.rb"
p App.settings[:file]
require 'yaml'
p App.settings.to_yaml
s = App.settings
#do stuff with s
App.settings.each do |key, value|
    #do something
end

Context

StackExchange Code Review Q#1015, answer score: 6

Revisions (0)

No revisions yet.