Appropriate use of constants

I am making a program that will load settings from a config file. I am
thinking of the best way to implement this. One idea is that the main
file could simply set constants that are equal to values loaded 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 get user set variables, and set these variables
as regular local variables internal to the individual methods.

I can see advantages and disadvantages to each technique.

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.

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

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 = ‘’

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
#--------------------------------

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: