Appropriate use of constants

I am making a program that will get settings from a config file. I am
thinking of the best way to implement this. One idea is that the main
file would simply set constants that are equal to values obtained from
the config file, then I could use those constants in the sections of
code where user configurable settings are relevant.

Another option would be to directly load from the config file in each of
the methods that need to user input, and set the variables as regular
local variables.

I can see advantages and disadvantages to each technique.

···

--
Posted via http://www.ruby-forum.com/.

Hi,

I'd use a single constant (like CONFIG), which holds a special object
representing the configuration values. This allows you to encapsulate
the technical stuff (file opening, parsing etc.) in the object.

Setting a constant for every value may be the second best possibilty, if
you put them into a module. But personally I don't like dynamically
created constants.

To load the values directly seems like a bad idea. First of all, it's
inefficient. And it forces you to deal with the file stuff again and
again -- this also makes the program very inflexible, because you'd have
to change all the methods if anything changes about the configuration
file.

···

--
Posted via http://www.ruby-forum.com/.

hi roob,

  if your program is also going to have some kind of settings manager,
so that the user can change various settings, you probably don't want
constants - but rather variables. i'd put all of the settings into a
module, that you later include in your main file. this way, if the
settings module is called `Settings`, and you have a variable in that
module called `@volume`, you can just call `Settings.volume` in the main
file to get the value.

  keep in mind that you'll also want to write in some way to create
default settings and a new settings file in case the original settings
file somehow goes missing...

  here's an example:

  - j

···

--
Posted via http://www.ruby-forum.com/.

jake kaiden wrote in post #1063123:

  here's an example:
gsWax/brains/shared.rb at master · lljk/gsWax · GitHub

I don't think a module is the right choice. Your code relies on the
programmer calling the "read" method before he reads or sets any value.
If he doesn't, he'll get strange errors.

I find these implicit dependencies rather confusing. It's probably
better to use an actual object which has the setup procedure in its
initialize method.

Also I wouldn't use an array to store the settings, because this is
rather error prone.

I'd probably do something like this:

···

#--------------------------------
class Settings

  DEFAULT_SETTINGS = {
    :foo_1 => 11,
    :foo_2 => 22,
    :foo_3 => 33
  }
  CONFIG_FILE_PATH = '<PATH>'

  def initialize
    begin
      # parse file
      @settings = '<FILE_CONTENT>'
    rescue
      @settings = DEFAULT_SETTINGS
      save!
    end
  end

  def save!
    # write settings to file
  end

  # getters and setters
  DEFAULT_SETTINGS.each_key do |config_key|
    define_method config_key do
      DEFAULT_SETTINGS[config_key]
    end
    define_method "#{config_key}=" do |val|
      DEFAULT_SETTINGS[config_key] = val
    end
  end

end
#--------------------------------

--
Posted via http://www.ruby-forum.com/\.

I'd probably do something like this:

...

  # getters and setters
  DEFAULT_SETTINGS.each_key do |config_key|
    define_method config_key do
      DEFAULT_SETTINGS[config_key]
    end
    define_method "#{config_key}=" do |val|
      DEFAULT_SETTINGS[config_key] = val
    end
  end

I think you mean @settings, not DEFAULT_SETTINGS?

Also I would be inclined to do

    @settings = DEFAULT_SETTINGS.dup

and to freeze DEFAULT_SETTINGS

But it may be simpler to do:

begin
  Settings = YAML.load("<settings_path>")
rescue
  # Set defaults
  Settings = {"foo"=>123, "bar"=>456}
end

If you want the accessor methods, you could use an OpenStruct, or this:

···

--
Posted via http://www.ruby-forum.com/\.