markbates-configatron 2.4.2.20090909140253 → 2.5.0.20090910111951

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: markbates-configatron
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.2.20090909140253
4
+ version: 2.5.0.20090910111951
5
5
  platform: ruby
6
6
  authors:
7
7
  - markbates
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-09-09 00:00:00 -07:00
12
+ date: 2009-09-10 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -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
@@ -52,7 +53,6 @@ files:
52
53
  - generators/templates/initializers/configatron.rb
53
54
  has_rdoc: false
54
55
  homepage: http://www.metabates.com
55
- licenses:
56
56
  post_install_message:
57
57
  rdoc_options: []
58
58
 
@@ -73,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
73
73
  requirements: []
74
74
 
75
75
  rubyforge_project: magrathea
76
- rubygems_version: 1.3.5
76
+ rubygems_version: 1.2.0
77
77
  signing_key:
78
78
  specification_version: 3
79
79
  summary: A powerful Ruby configuration system.