configfiles 0.3.1 → 0.3.2

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.
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