public
Description: A super cool, simple, and feature rich configuration system for Ruby apps. (replaces application_configuration)
Homepage: http://www.mackframework.com
Clone URL: git://github.com/markbates/configatron.git
Click here to lend your support to: configatron and make a donation at www.pledgie.com !
commit  b1eeede854d614ba5f7ec74159dd0c622e0594bb
tree    00ca596682e42d011606cfcd0d6ef369be67ebe4
parent  d8475cd8f3dceb654fbbb7c826b3bb4b655b9001
configatron / README
100644 189 lines (125 sloc) 7.916 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
=Configatron
 
Configatron makes configuring your applications and scripts incredibly easy. No longer is a there a need to use constants or global variables. Now you can use a simple and painless system to configure your life. And, because it's all Ruby, you can do any crazy thing you would like to!
 
==Installation
 
Installation of Configatron is easy, as it is just a RubyGem:
 
  $ sudo gem install configatron
 
If you'd like to live on the bleedin' edge you can install the development version from GitHub:
 
  $ sudo gem install markbates-configatron --source=http://gems.github.com
 
Once installed you just need to require it:
 
  require 'configatron'
 
==Examples
 
===Simple
 
  configatron.email = 'me@example.com'
  configatron.database_url = "postgres://localhost/mack_framework_rocks"
 
Now, anywhere in your code you can do the following:
 
  configatron.email # => "me@example.com"
  configatron.database_url # => "postgres://localhost/mack_framework_rocks"
 
Viola! Simple as can be.
 
Now you're saying, what if I want to have a 'default' set of options, but then override them later, based on other information? Simple again. Let's use our above example. We've configured our <tt>database_url</tt> option to be <tt>postgres://localhost/mack_framework_rocks</tt>. The problem with that is that is our production database url, not our development url. Fair enough, all you have to do is redeclare it:
 
  configatron.database_url = "postgres://localhost/mack_framework_rocks_development"
 
becomes:
 
  configatron.email # => "me@example.com"
  configatron.database_url # => "postgres://localhost/mack_framework_rocks_development"
 
Notice how our other configuration parameters haven't changed? Cool, eh?
 
===Hash/YAML
 
You can configure configatron from a hash as well:
 
  configatron.configure_from_hash({:email => {:pop => {:address => 'pop.example.com', :port => 110}}, :smtp => {:address => 'smtp.example.com'}})
  
  configatron.email.pop.address # => 'pop.example.com'
  configatron.email.pop.port # => 110
  # and so on...
 
Notice how they're all namespaced for your as well. The same holds true for YAML files:
 
  configatron.configure_from_yaml('/path/to/file.yml')
 
===Namespaces
 
The question that should be on your lips is what I need to have namespaced configuration parameters. It's easy! Configatron allows you to create namespaces.
 
  configatron.website_url = "http://www.mackframework.com"
  configatron.email.pop.address = "pop.example.com"
  configatron.email.pop.port = 110
  configatron.email.smtp.address = "smtp.example.com"
  configatron.email.smtp.port = 25
 
becomes:
 
  configatron.email.pop.address # => "pop.example.com"
  configatron.email.smtp.address # => "smtp.example.com"
  configatron.website_url # => "http://www.mackframework.com"
 
Configatron allows you to nest namespaces to your hearts content! Just keep going, it's that easy.
 
Of course you can update a single parameter n levels deep as well:
 
  configatron.email.pop.address = "pop2.example.com"
  
  configatron.email.pop.address # => "pop2.example.com"
  configatron.email.smtp.address # => "smtp.example.com"
 
===Temp Configurations
 
Sometimes in testing, or other situations, you want to temporarily change some settings. You can do this with the <tt>temp</tt> method:
 
  configatron.one = 1
  configatron.letters.a = 'A'
  configatron.letters.b = 'B'
  configatron.temp do
    configatron.letters.b = 'bb'
    configatron.letters.c = 'c'
    configatron.one # => 1
    configatron.letters.a # => 'A'
    configatron.letters.b # => 'bb'
    configatron.letters.c # => 'c'
  end
  configatron.one # => 1
  configatron.letters.a # => 'A'
  configatron.letters.b # => 'B'
  configatron.letters.c # => nil
 
You can also pass in an optional Hash to the <tt>temp</tt>:
 
  configatron.one = 1
  configatron.letters.a = 'A'
  configatron.letters.b = 'B'
  configatron.temp(:letters => {:b => 'bb', :c => 'c'}) do
    configatron.one == 1
    configatron.letters.a # => 'A'
    configatron.letters.b # => 'bb'
    configatron.letters.c # => 'c'
  end
  configatron.one == 1
  configatron.letters.a # => 'A'
  configatron.letters.b # => 'B'
  configatron.letters.c # => nil
 
===Delayed and Dynamic Configurations
 
There are times when you want to refer to one configuration setting in another configuration setting. Let's look at a fairly contrived example:
 
  configatron.memcached.servers = ['127.0.0.1:11211']
  configatron.page_caching.servers = configatron.memcached.servers
  configatron.object_caching.servers = configatron.memcached.servers
 
  if RAILS_ENV == 'production'
    configatron.memcached.servers = ['192.168.0.1:11211']
    configatron.page_caching.servers = configatron.memcached.servers
    configatron.object_caching.servers = configatron.memcached.servers
  elsif RAILS_ENV == 'staging'
    configatron.memcached.servers = ['192.168.0.2:11211']
    configatron.page_caching.servers = configatron.memcached.servers
    configatron.object_caching.servers = configatron.memcached.servers
  end
 
Now, we could've written that slightly differently, but it helps to illustrate the point. With Configatron you can create <code>Delayed</code> and <code>Dynamic</code> settings.
 
====Delayed
 
With <code>Delayed</code> settings execution of the setting doesn't happen until the first time it is executed.
 
  configatron.memcached.servers = ['127.0.0.1:11211']
  configatron.page_caching.servers = Configatron::Delayed.new {configatron.memcached.servers}
  configatron.object_caching.servers = Configatron::Delayed.new {configatron.memcached.servers}
 
  if RAILS_ENV == 'production'
    configatron.memcached.servers = ['192.168.0.1:11211']
  elsif RAILS_ENV == 'staging'
    configatron.memcached.servers = ['192.168.0.2:11211']
  end
 
Execution occurs once and after that the result of that execution is returned. So in our case the first time someone calls the setting <code>configatron.page_caching.servers</code> it will find the <code>configatron.memcached.servers</code> setting and return that. After that point if the <code>configatron.memcached.servers</code> setting is changed, the original settings are returned by <code>configatron.page_caching.servers</code>.
 
====Dynamic
 
<code>Dynamic</code> settings are very similar to <code>Delayed</code> settings, but with one big difference. Every time you call a <code>Dynamic</code> setting is executed. Take this example:
 
  configatron.current.time = Configatron::Dynamic.new {Time.now}
 
Each time you call <code>configatron.current.time</code> it will return a new value to you. While this seems a bit useless, it is pretty useful if you have ever changing configurations.
 
===Misc.
 
Even if parameters haven't been set, you can still call them, but you'll get a <tt>Configatron::Store</tt> object back. The Configatron::Store class, however, will respond true to <tt>.nil?</tt> if there are no parameters configured on it.
 
  configatron.i.dont.exist.nil? # => true
  configatron.i.dont.exist # => Configatron::Store
 
If you want to get back an actual <tt>nil</tt> then you can use the <tt>retrieve</tt> method:
 
  configatron.i.do.exist = [:some, :array]
  configatron.i.dont.retrieve(:exist, nil) # => nil
  configatron.i.do.retrieve(:exist, :foo) # => [:some, :array]
 
You can set 'default' values for parameters. If there is already a setting, it won't be replaced. This is useful if you've already done your 'configuration' and you call a library, that needs to have parameters set. The library can set its defaults, without worrying that it might have overridden your custom settings.
 
  configatron.set_default(:name, 'Mark Bates')
  configatron.name # => 'Mark Bates'
  configatron.set_default(:name, 'Me')
  configatron.name # => 'Mark Bates'
 
Enjoy!
 
==Contact
 
Please mail bugs, suggestions and patches to "development@metabates.com":mailto:development@metabates.com
 
On the web at: "http://www.metabates.com":http://www.metabates.com