configatron 2.4.2 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -80,25 +80,7 @@ Of course you can update a single parameter n levels deep as well:
80
80
  configatron.email.pop.address # => "pop2.example.com"
81
81
  configatron.email.smtp.address # => "smtp.example.com"
82
82
 
83
- ===Misc.
84
-
85
- 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.
86
-
87
- configatron.i.dont.exist.nil? # => true
88
- configatron.i.dont.exist # => Configatron::Store
89
-
90
- If you want to get back an actual <tt>nil</tt> then you can use the <tt>retrieve</tt> method:
91
-
92
- configatron.i.do.exist = [:some, :array]
93
- configatron.i.dont.retrieve(:exist, nil) # => nil
94
- configatron.i.do.retrieve(:exist, :foo) # => [:some, :array]
95
-
96
- 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.
97
-
98
- configatron.set_default(:name, 'Mark Bates')
99
- configatron.name # => 'Mark Bates'
100
- configatron.set_default(:name, 'Me')
101
- configatron.name # => 'Mark Bates'
83
+ ===Temp Configurations
102
84
 
103
85
  Sometimes in testing, or other situations, you want to temporarily change some settings. You can do this with the <tt>temp</tt> method:
104
86
 
@@ -134,6 +116,70 @@ You can also pass in an optional Hash to the <tt>temp</tt>:
134
116
  configatron.letters.b # => 'B'
135
117
  configatron.letters.c # => nil
136
118
 
119
+ ===Delayed and Dynamic Configurations
120
+
121
+ There are times when you want to refer to one configuration setting in another configuration setting. Let's look at a fairly contrived example:
122
+
123
+ configatron.memcached.servers = ['127.0.0.1:11211']
124
+ configatron.page_caching.servers = configatron.memcached.servers
125
+ configatron.object_caching.servers = configatron.memcached.servers
126
+
127
+ if RAILS_ENV == 'production'
128
+ configatron.memcached.servers = ['192.168.0.1:11211']
129
+ configatron.page_caching.servers = configatron.memcached.servers
130
+ configatron.object_caching.servers = configatron.memcached.servers
131
+ elsif RAILS_ENV == 'staging'
132
+ configatron.memcached.servers = ['192.168.0.2:11211']
133
+ configatron.page_caching.servers = configatron.memcached.servers
134
+ configatron.object_caching.servers = configatron.memcached.servers
135
+ end
136
+
137
+ 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.
138
+
139
+ ====Delayed
140
+
141
+ With <code>Delayed</code> settings execution of the setting doesn't happen until the first time it is executed.
142
+
143
+ configatron.memcached.servers = ['127.0.0.1:11211']
144
+ configatron.page_caching.servers = Configatron::Delayed.new {configatron.memcached.servers}
145
+ configatron.object_caching.servers = Configatron::Delayed.new {configatron.memcached.servers}
146
+
147
+ if RAILS_ENV == 'production'
148
+ configatron.memcached.servers = ['192.168.0.1:11211']
149
+ elsif RAILS_ENV == 'staging'
150
+ configatron.memcached.servers = ['192.168.0.2:11211']
151
+ end
152
+
153
+ 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>.
154
+
155
+ ====Dynamic
156
+
157
+ <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:
158
+
159
+ configatron.current.time = Configatron::Dynamic.new {Time.now}
160
+
161
+ 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.
162
+
163
+ ===Misc.
164
+
165
+ 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.
166
+
167
+ configatron.i.dont.exist.nil? # => true
168
+ configatron.i.dont.exist # => Configatron::Store
169
+
170
+ If you want to get back an actual <tt>nil</tt> then you can use the <tt>retrieve</tt> method:
171
+
172
+ configatron.i.do.exist = [:some, :array]
173
+ configatron.i.dont.retrieve(:exist, nil) # => nil
174
+ configatron.i.do.retrieve(:exist, :foo) # => [:some, :array]
175
+
176
+ 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.
177
+
178
+ configatron.set_default(:name, 'Mark Bates')
179
+ configatron.name # => 'Mark Bates'
180
+ configatron.set_default(:name, 'Me')
181
+ configatron.name # => 'Mark Bates'
182
+
137
183
  Enjoy!
138
184
 
139
185
  ==Contact
data/lib/configatron.rb CHANGED
@@ -8,4 +8,5 @@ require File.join(base, 'core_ext', 'kernel')
8
8
  require File.join(base, 'core_ext', 'object')
9
9
  require File.join(base, 'core_ext', 'string')
10
10
  require File.join(base, 'core_ext', 'class')
11
- require File.join(base, 'rails')
11
+ require File.join(base, 'rails')
12
+ require File.join(base, 'proc')
@@ -0,0 +1,104 @@
1
+ class Configatron
2
+ # This class can be used to give special powers to a Configatron setting.
3
+ # See Configatron::Delayed and Configatron::Dynamic as examples of how this
4
+ # works.
5
+ #
6
+ # This class can be subclassed easily. The key is to override the <tt>finalize?</tt>
7
+ # method.
8
+ #
9
+ # Example:
10
+ # class RunThreeTimes < Configatron::Proc
11
+ # def finalize?
12
+ # self.execution_count == 3
13
+ # end
14
+ # end
15
+ #
16
+ # configatron.some.rand.generator = RunThreeTimes.new do
17
+ # rand
18
+ # end
19
+ #
20
+ # configatron.some.rand.generator # => 0.169280668547299
21
+ # configatron.some.rand.generator # => 0.298880544243205
22
+ # configatron.some.rand.generator # => 0.421091617110779
23
+ # configatron.some.rand.generator # => 0.421091617110779
24
+ # configatron.some.rand.generator # => 0.421091617110779
25
+ class Proc
26
+
27
+ # The number of times this Proc has been executed
28
+ attr_accessor :execution_count
29
+ # The block that you want executed when you call the <tt>execute</tt> method.
30
+ attr_accessor :block
31
+
32
+ # Requires a block to be passed into it.
33
+ def initialize(&block)
34
+ self.execution_count = 0
35
+ self.block = block
36
+ end
37
+
38
+ # Executes the <tt>block</tt> attribute, ticks up the
39
+ # <tt>execution_count</tt> attribute by one and then
40
+ # returns the value of the executed <tt>block</tt>
41
+ def execute
42
+ val = self.block.call
43
+ self.execution_count += 1
44
+ return val
45
+ end
46
+
47
+ # Returns <tt>true</tt> if Configatron should cache the
48
+ # results of the <tt>execute</tt> method, thereby never calling
49
+ # it again.
50
+ def finalize?
51
+ self.execution_count == 1
52
+ end
53
+
54
+ end
55
+
56
+ # Tells Configatron to always execute the block at runtime.
57
+ # The results will never be cached.
58
+ #
59
+ # Example:
60
+ # configatron.letters = 'a-b-c-d'
61
+ # configatron.my.letters = Configatron::Delayed.new do
62
+ # "My letters are: #{configatron.letters}"
63
+ # end
64
+ # configatron.my.other.letters = Configatron::Dynamic.new do
65
+ # "My letters are: #{configatron.a.b.c.d}"
66
+ # end
67
+ #
68
+ # configatron.my.letters # => 'My letters are: a-b-c-d'
69
+ # configatron.my.other.letters # => 'My letters are: a-b-c-d'
70
+ #
71
+ # configatron.letters = 'a-b-c-d-e'
72
+ #
73
+ # configatron.my.letters # => 'My letters are: a-b-c-d'
74
+ # configatron.my.other.letters # => 'My letters are: a-b-c-d-e'
75
+ class Dynamic < Configatron::Proc
76
+ def finalize?
77
+ false
78
+ end
79
+ end
80
+
81
+ # Tells Configatron to delay execution of the block until
82
+ # runtime. Once run the results of the block will be cached,
83
+ # never to be run again.
84
+ #
85
+ # Example:
86
+ # configatron.letters = 'a-b-c-d'
87
+ # configatron.my.letters = Configatron::Delayed.new do
88
+ # "My letters are: #{configatron.letters}"
89
+ # end
90
+ # configatron.my.other.letters = Configatron::Dynamic.new do
91
+ # "My letters are: #{configatron.a.b.c.d}"
92
+ # end
93
+ #
94
+ # configatron.my.letters # => 'My letters are: a-b-c-d'
95
+ # configatron.my.other.letters # => 'My letters are: a-b-c-d'
96
+ #
97
+ # configatron.letters = 'a-b-c-d-e'
98
+ #
99
+ # configatron.my.letters # => 'My letters are: a-b-c-d'
100
+ # configatron.my.other.letters # => 'My letters are: a-b-c-d-e'
101
+ class Delayed < Configatron::Proc
102
+ end
103
+
104
+ end
@@ -113,7 +113,8 @@ class Configatron
113
113
  # it won't set the value.
114
114
  def set_default(name, default_value)
115
115
  unless @_store[name.to_sym]
116
- @_store[name.to_sym] = parse_options(default_value)
116
+ # @_store[name.to_sym] = parse_options(default_value)
117
+ self.send("#{name}=", default_value)
117
118
  end
118
119
  end
119
120
 
@@ -124,7 +125,15 @@ class Configatron
124
125
  raise Configatron::LockedNamespace.new(@_name) if @_locked && !@_store.has_key?(name)
125
126
  @_store[name] = parse_options(*args)
126
127
  elsif @_store.has_key?(sym)
127
- return @_store[sym]
128
+ val = @_store[sym]
129
+ if val.is_a?(Configatron::Proc)
130
+ res = val.execute
131
+ if val.finalize?
132
+ @_store[sym] = res
133
+ end
134
+ return res
135
+ end
136
+ return val
128
137
  else
129
138
  store = Configatron::Store.new({}, sym, self)
130
139
  @_store[sym] = store
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: configatron
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.2
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
- - root
7
+ - markbates
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-09-09 00:00:00 -04:00
12
+ date: 2009-09-10 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -22,7 +22,7 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: 0.1.0
24
24
  version:
25
- description: "configatron was developed by: root"
25
+ description: "configatron was developed by: markbates"
26
26
  email: mark@markbates.com
27
27
  executables: []
28
28
 
@@ -38,6 +38,7 @@ files:
38
38
  - lib/configatron/core_ext/object.rb
39
39
  - lib/configatron/core_ext/string.rb
40
40
  - lib/configatron/errors.rb
41
+ - lib/configatron/proc.rb
41
42
  - lib/configatron/rails.rb
42
43
  - lib/configatron/store.rb
43
44
  - lib/configatron.rb