# Where should I put my config file, and how to load it?

**URL:** <https://www.ruby-forum.com/t/where-should-i-put-my-config-file-and-how-to-load-it/179423>\
**Category:** Ruby\
**Created:** [November 24, 2009, 5:34pm UTC](https://www.ruby-forum.com/t/where-should-i-put-my-config-file-and-how-to-load-it/179423 "2009-11-24T17:34:08Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![kozuka](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f4b2a3/32.png) [@kozuka](https://www.ruby-forum.com/u/kozuka)\
**Post date:** [November 24, 2009, 5:34pm UTC](https://www.ruby-forum.com/t/where-should-i-put-my-config-file-and-how-to-load-it/179423/1 "2009-11-24T17:34:08Z")

</div>

Hello all!

I have a small app/set of libraries I’m developing at work called  
Sweet. I’m distributing it internally as a ruby gem, which is working  
nicely. However I rather foolishly put Sweet’s yaml config file in its  
config/ directory, so now every time the gem gets upgraded, it wipes  
out the current settings. Oops! My plan to fix this problem is to  
store the config file at ~/.sweetrc, with a global config file at  
/etc/sweetrc to fall back to if the home directory one isn’t  
available. Does this sound like a sensible solution? Or am I going  
mad?

The second (and more ruby-ish) question I have is: How can I make sure  
all my classes have access to the contents of the config file? My  
classes all reside within the ‘Sweet’ module, and ideally I would like  
to be able to do something along the lines of

@data\_directory = Sweet::Config[‘data\_directory’]

in the initialisation method of any of my classes. Previously all of  
the code was pretty much in one class, so that class just had a method  
to load the yaml, but I’m doing a pretty major refactoring for Sweet  
v2.

Any assistance would be greatly appreciated!

- Ian 🙂

(Instances of the words ‘config file’ in this email: 4)

---

<div class="post-metadata">

**Author:** ![kozuka](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f4b2a3/32.png) [@kozuka](https://www.ruby-forum.com/u/kozuka)\
**Post date:** [November 24, 2009, 6:25pm UTC](https://www.ruby-forum.com/t/where-should-i-put-my-config-file-and-how-to-load-it/179423/2 "2009-11-24T18:25:11Z")

</div>

Ian B. wrote:

> Hello all!
> 
> I have a small app/set of libraries I’m developing at work called  
> Sweet. I’m distributing it internally as a ruby gem, which is working  
> nicely. However I rather foolishly put Sweet’s yaml config file in its  
> config/ directory, so now every time the gem gets upgraded, it wipes  
> out the current settings. Oops! My plan to fix this problem is to  
> store the config file at ~/.sweetrc, with a global config file at  
> /etc/sweetrc to fall back to if the home directory one isn’t  
> available. Does this sound like a sensible solution?

Only if your gem is meant as an executable application.

> Or am I going  
> mad?
> 
> The second (and more ruby-ish) question I have is: How can I make sure  
> all my classes have access to the contents of the config file? My  
> classes all reside within the ‘Sweet’ module, and ideally I would like  
> to be able to do something along the lines of
> 
> @data\_directory = Sweet::Config[‘data\_directory’]
> 
> in the initialisation method of any of my classes. Previously all of  
> the code was pretty much in one class, so that class just had a method  
> to load the yaml, but I’m doing a pretty major refactoring for Sweet  
> v2.

Put the yaml in the Config object.

> Any assistance would be greatly appreciated!
> 
> - Ian 🙂
> 
> (Instances of the words ‘config file’ in this email: 4)

## Best,

Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![kozuka](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f4b2a3/32.png) [@kozuka](https://www.ruby-forum.com/u/kozuka)\
**Post date:** [November 24, 2009, 7:28pm UTC](https://www.ruby-forum.com/t/where-should-i-put-my-config-file-and-how-to-load-it/179423/3 "2009-11-24T19:28:51Z")

</div>

On Tuesday 24 November 2009 10:33:18 am Ian B. wrote:

> My plan to fix this problem is to  
> store the config file at ~/.sweetrc, with a global config file at  
> /etc/sweetrc to fall back to if the home directory one isn’t  
> available.

Depending what the config file looks like, you may want to allow the  
global  
one to be overridden by the local one – that is, something to the  
effect of:

global\_options.merge(local\_options)

Also, I wouldn’t insist on putting anything in /etc. If users want to  
create  
/etc/sweetrc, go for it, but I’d say default back to something inside  
your  
gem, so no installation other than ‘gem install’ is required.

Also, it’s probably not an rc, since it’s yaml. It’s probably a .yaml or  
.conf. The ‘rc’ stands for ‘run command’, which implies it’s an actual  
script  
– compare to, for example, irbrc.

> The second (and more ruby-ish) question I have is: How can I make sure  
> all my classes have access to the contents of the config file? My  
> classes all reside within the ‘Sweet’ module, and ideally I would like  
> to be able to do something along the lines of
> 
> @data\_directory = Sweet::Config[‘data\_directory’]

That makes sense, if you actually need that to be inside the class. You  
probably also want it to be possible to override by specific instances  
of the  
class, or by someone calling the class, but that might be overkill.

---

<div class="post-metadata">

**Author:** ![kozuka](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f4b2a3/32.png) [@kozuka](https://www.ruby-forum.com/u/kozuka)\
**Post date:** [November 25, 2009, 1:30pm UTC](https://www.ruby-forum.com/t/where-should-i-put-my-config-file-and-how-to-load-it/179423/4 "2009-11-25T13:30:27Z")

</div>

On Nov 24, 11:33 am, Ian B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> mad?  
> Please, don’t use ~/.sweetrc. Be cool and kind and use XDG standard.

[XDG Base Directory Specification](http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html)  
[http://xdg.rubyforge.org/](http://xdg.rubyforge.org/)

> The second (and more ruby-ish) question I have is: How can I make sure  
> all my classes have access to the contents of the config file? My  
> classes all reside within the ‘Sweet’ module, and ideally I would like  
> to be able to do something along the lines of
> 
> @data\_directory = Sweet::Config[‘data\_directory’]

Off the top of my head:

class Sweet::Config  
DEFAULTS = {… }  
def initialize  
file = XDG.config\_find(‘sweet/config.yaml’)  
data = file ? YAML.load(File.new(file)) : {}  
@data = DEFAULTS.merge(data)  
end  
def self.global  
@global ||= new  
end  
def self.  
global[key.to\_s]  
end  
end

---

<div class="post-metadata">

**Author:** ![kozuka](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f4b2a3/32.png) [@kozuka](https://www.ruby-forum.com/u/kozuka)\
**Post date:** [November 26, 2009, 10:10am UTC](https://www.ruby-forum.com/t/where-should-i-put-my-config-file-and-how-to-load-it/179423/5 "2009-11-26T10:10:02Z")

</div>

Thanks for all the responses, guys, this has given me plenty to think  
about! 🙂

- Ian

---

<div class="post-metadata">

**Author:** ![kozuka](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f4b2a3/32.png) [@kozuka](https://www.ruby-forum.com/u/kozuka)\
**Post date:** [November 25, 2009, 11:11am UTC](https://www.ruby-forum.com/t/where-should-i-put-my-config-file-and-how-to-load-it/179423/6 "2009-11-25T11:11:22Z")

</div>

Ian B. wrote:

> My plan to fix this problem is to  
> store the config file at ~/.sweetrc, with a global config file at  
> /etc/sweetrc to fall back to if the home directory one isn’t  
> available. Does this sound like a sensible solution? Or am I going  
> mad?

If your config is simple, you could just load the hard-coded defaults  
into a hash, load in the user’s config from .sweetrc into another hash,  
and then use merge() so that the final config consists of the defaults  
with the user’s overrides.

If it’s more complex or you want to provide the user with a config  
template to edit, you could check if ~/.sweetrc exists, and if it  
doesn’t then copy config/sweetrc.default to ~/.sweetrc

However the latter approach may store up problems for the future. If  
your config file format changes, or you add new mandatory parameters,  
then users may end up running the new code with the old config, and  
you’ll have to provide a migration tool to merge their old settings with  
the new ones.

So what you really want to do is to identify settings which are new  
(merge them in), and those which are obsolete (and remove them). The  
solution used by courier-mta is called sysconftool, and it marks up the  
config with special comments to identify the sections.  
[http://www.courier-mta.org/sysconftool/](http://www.courier-mta.org/sysconftool/)

There’s a ruby implementation that I wrote ages ago:  
[http://rconftool.rubyforge.org/](http://rconftool.rubyforge.org/)

> The second (and more ruby-ish) question I have is: How can I make sure  
> all my classes have access to the contents of the config file? My  
> classes all reside within the ‘Sweet’ module, and ideally I would like  
> to be able to do something along the lines of
> 
> @data\_directory = Sweet::Config[‘data\_directory’]
> 
> in the initialisation method of any of my classes. Previously all of  
> the code was pretty much in one class, so that class just had a method  
> to load the yaml, but I’m doing a pretty major refactoring for Sweet  
> v2.

I think that’s fine. You can put the config-reading code into  
sweet/config.rb, so that the clients just need to do  
require ‘sweet/config’  
to ensure the Sweet::Config object is available.
