configfiles 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/Changelog +12 -0
  2. data/lib/configfiles.rb +50 -34
  3. metadata +2 -2
data/Changelog CHANGED
@@ -1,8 +1,20 @@
1
+ 0.3.2
2
+
3
+ * implementation based on class instance variables
4
+ * fixes data clobbering between inherited classes
5
+
6
+ 0.3.1
7
+
8
+ * fix serious typos in Base#load
9
+
1
10
  0.3.0
11
+
2
12
  * options to avoid validation and extra computation on Base#load
3
13
 
4
14
  0.2.0
15
+
5
16
  * add 'virtual' parameter
6
17
 
7
18
  0.1.0
19
+
8
20
  * first non-alpha release
data/lib/configfiles.rb CHANGED
@@ -7,7 +7,7 @@ require 'configfiles/extensions/enumerable'
7
7
 
8
8
  module ConfigFiles
9
9
 
10
- VERSION = '0.3.1'
10
+ VERSION = '0.3.2'
11
11
 
12
12
  # You should write a read(io) method,
13
13
  # taking an IO object and returnig a key-value hash, where keys
@@ -28,18 +28,32 @@ module ConfigFiles
28
28
  class DefaultAlreadySet < ::Exception; end
29
29
  class VirtualParameterFound < ::RuntimeError; end
30
30
 
31
- @@parameters ||= {}
32
- @@behavior ||= {
33
- :unknown_parameter => :ignore,
34
- :unknown_value => :fail # when the converter is a Hash,
35
- # whose keys represents a fixed set
36
- # of allowed strings, and values represents
37
- # their "meaning", tipically as a Symbol
38
- }
39
- @@validate ||= lambda {|data| true}
40
-
41
31
  class << self
42
32
 
33
+ # NOTE: *class instance variables* to avoid overlapping when you have
34
+ # several inherited classes! See "The Ruby Programming Language" by David
35
+ # Flanagan and Yukihiro Matsumoto, 2008, O'Really, 978-0-596-51617-8,
36
+ # sec 7.1.16
37
+
38
+ # *class instance variables* accessors
39
+ attr_accessor :parameters, :behavior, :validation
40
+
41
+ def inherited(subclass)
42
+ subclass.class_instance_initialize
43
+ end
44
+
45
+ def class_instance_initialize
46
+ @parameters ||= {}
47
+ @behavior ||= {
48
+ :unknown_parameter => :ignore,
49
+ :unknown_value => :fail # when the converter is a Hash,
50
+ # whose keys represents a fixed set
51
+ # of allowed strings, and values represents
52
+ # their "meaning", tipically as a Symbol
53
+ }
54
+ @validation ||= lambda {|data| true}
55
+ end
56
+
43
57
  # Examples:
44
58
  # on :unknown_parameter, :fail # or :accept, or :ignore
45
59
  # on :unknown_parameter, {|str| str.to_i}
@@ -55,13 +69,13 @@ module ConfigFiles
55
69
  raise ArgumentError, "Invalid circumstance: #{circumstance.inspect}. Allowed values are #{circumstances.list_inspect}."
56
70
  end
57
71
  if block
58
- @@behavior[circumstance] = block
72
+ @behavior[circumstance] = block
59
73
  elsif actions.include? action
60
- @@behavior[circumstance] = action
74
+ @behavior[circumstance] = action
61
75
  elsif action
62
76
  raise ArgumentError, "Invalid action: #{action}. Allowed values are #{actions.list_inspect}."
63
77
  else
64
- return @@behavior[circumstance]
78
+ return @behavior[circumstance]
65
79
  end
66
80
  end
67
81
 
@@ -91,7 +105,7 @@ module ConfigFiles
91
105
  # '2' => :my_second_one
92
106
  #
93
107
  def parameter(name, converter=nil, &converter_block)
94
- if @@parameters[name] and @@parameters[name][:converter]
108
+ if @parameters[name] and @parameters[name][:converter]
95
109
  raise AlreadyDefinedParameter, "Already defined parameter \"#{name}\""
96
110
  end
97
111
  if converter
@@ -102,9 +116,9 @@ module ConfigFiles
102
116
  converter_block = lambda do |x| # x is a String from conf file
103
117
  if converter.keys.include? x
104
118
  return converter[x] # returns from lambda, not from method
105
- elsif @@behavior[:unknown_value] == :fail
119
+ elsif @behavior[:unknown_value] == :fail
106
120
  raise ArgumentError, "Invalid value \"#{x}\" for parameter \"#{name}\". Allowed values are #{converter.keys.list_inspect}."
107
- elsif @@behavior[:unknown_value] == :accept
121
+ elsif @behavior[:unknown_value] == :accept
108
122
  return x
109
123
  end
110
124
  end
@@ -115,17 +129,17 @@ module ConfigFiles
115
129
  else
116
130
  converter_block ||= lambda {|x| x}
117
131
  end
118
- @@parameters[name] ||= {}
119
- @@parameters[name][:converter] = converter_block
132
+ @parameters[name] ||= {}
133
+ @parameters[name][:converter] = converter_block
120
134
  end
121
135
 
122
136
  # set default value of a parameter
123
137
  def default(name, value)
124
- if @@parameters[name] and @@parameters[name][:default]
125
- raise DefaultAlreadySet, "Default for \"#{name}\" has been already set (to value: #{@@parameters[name][:default]})"
138
+ if @parameters[name] and @parameters[name][:default]
139
+ raise DefaultAlreadySet, "Default for \"#{name}\" has been already set (to value: #{@parameters[name][:default]})"
126
140
  end
127
- @@parameters[name] ||= {}
128
- @@parameters[name][:default] = value
141
+ @parameters[name] ||= {}
142
+ @parameters[name][:default] = value
129
143
  end
130
144
 
131
145
  # Define a parameter as a function of other parameters.
@@ -181,7 +195,7 @@ module ConfigFiles
181
195
  # end
182
196
  #
183
197
  def validate(&block)
184
- @@validate = block
198
+ @validation = block
185
199
  end
186
200
 
187
201
  end # class << self
@@ -193,7 +207,7 @@ module ConfigFiles
193
207
  # Validate configuration object, according to what declared
194
208
  # with the class method
195
209
  def validate
196
- @@validate.call(self)
210
+ self.class.validation.call(self)
197
211
  end
198
212
 
199
213
  # Load the Hash h onto the ConfigFiles object, carrying on conversions
@@ -222,23 +236,23 @@ module ConfigFiles
222
236
  opt_h = opt_h_defaults.merge(opt_h)
223
237
 
224
238
  h.each_pair do |id, value|
225
- if @@parameters[id] and @@parameters[id][:converter]
226
- @data[id] = @@parameters[id][:converter].call(value)
227
- elsif @@behavior[:unknown_parameter] == :fail
239
+ if self.class.parameters[id] and self.class.parameters[id][:converter]
240
+ @data[id] = self.class.parameters[id][:converter].call(value)
241
+ elsif self.class.behavior[:unknown_parameter] == :fail
228
242
  raise RuntimeError, "unknown parameter #{key}" # otherwise ignore
229
- elsif @@behavior[:unknown_parameter] == :accept
243
+ elsif self.class.behavior[:unknown_parameter] == :accept
230
244
  @data[id] = value
231
- elsif @@behavior[:unknown_parameter].respond_to? :call
232
- block = @@behavior[:unknown_parameter]
245
+ elsif self.class.behavior[:unknown_parameter].respond_to? :call
246
+ block = self.class.behavior[:unknown_parameter]
233
247
  @data[id] = block.call value
234
248
  end
235
249
  end
236
250
 
237
251
  if opt_h[:compute_defaults]
238
252
  # assign default values to the remaining params
239
- @@parameters.each_pair do |name, h|
240
- if !@data[name] and @@parameters[name][:default]
241
- @data[name] = @@parameters[name][:default]
253
+ self.class.parameters.each_pair do |name, h|
254
+ if !@data[name] and self.class.parameters[name][:default]
255
+ @data[name] = self.class.parameters[name][:default]
242
256
  end
243
257
  end
244
258
  end
@@ -288,3 +302,5 @@ module ConfigFiles
288
302
 
289
303
  end
290
304
  end
305
+
306
+ ConfigFiles::Base.class_instance_initialize
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 3
8
- - 1
9
- version: 0.3.1
8
+ - 2
9
+ version: 0.3.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Guido De Rosa