configurable 0.5.0 → 0.6.0

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.
@@ -1,16 +1,12 @@
1
1
  module Configurable
2
2
 
3
- # Utility methods to dump and load configurations, particularly nested
4
- # configurations.
3
+ # Utility methods to dump and load Configurable class configurations.
5
4
  module Utils
6
5
  module_function
7
6
 
8
- default_dump_block = lambda do |key, delegate|
9
- default = delegate.default(false)
10
-
7
+ default_dump_block = lambda do |key, config|
11
8
  # note: this causes order to be lost...
12
- default = default.to_hash if delegate.is_nest?
13
- YAML.dump({key => default})[5..-1]
9
+ YAML.dump({key => config.default})[5..-1]
14
10
  end
15
11
 
16
12
  # A block performing the default YAML dump.
@@ -23,9 +19,9 @@ module Configurable
23
19
  # A block performing the default load.
24
20
  DEFAULT_LOAD = default_load_block
25
21
 
26
- # Dumps delegates to target as yaml. Delegates are output in order, and
27
- # symbol keys are be stringified if delegates has been extended with
28
- # IndifferentAccess (this produces a nicer config file).
22
+ # Dumps configurations to target as yaml. Configs are output in order,
23
+ # and symbol keys are be stringified if configurations has been extended
24
+ # with IndifferentAccess (this produces a nicer config file).
29
25
  #
30
26
  # class DumpExample
31
27
  # include Configurable
@@ -40,7 +36,7 @@ module Configurable
40
36
  # # str: value
41
37
  # # }
42
38
  #
43
- # Dump may be provided with a block to format each (key, delegate) pair;
39
+ # Dump may be provided with a block to format each (key, Config) pair;
44
40
  # the block results are pushed directly to target, so newlines must be
45
41
  # specified manually.
46
42
  #
@@ -57,27 +53,27 @@ module Configurable
57
53
  # #
58
54
  # # }
59
55
  #
60
- def dump(delegates, target="")
61
- return dump(delegates, target, &DEFAULT_DUMP) unless block_given?
56
+ def dump(configs, target="")
57
+ return dump(configs, target, &DEFAULT_DUMP) unless block_given?
62
58
 
63
- stringify = delegates.kind_of?(IndifferentAccess)
64
- delegates.each_pair do |key, delegate|
59
+ stringify = configs.kind_of?(IndifferentAccess)
60
+ configs.each_pair do |key, config|
65
61
  key = key.to_s if stringify && key.kind_of?(Symbol)
66
- target << yield(key, delegate)
62
+ target << yield(key, config)
67
63
  end
68
64
 
69
65
  target
70
66
  end
71
67
 
72
- # Dumps the delegates to the specified file. If recurse is true, nested
73
- # configurations are each dumped to their own file, based on the nesting
68
+ # Dumps the configurations to the specified file. If recurse is true,
69
+ # nested configs are each dumped to their own file, based on the nesting
74
70
  # key. For instance if you nested a in b:
75
71
  #
76
72
  # a_configs = {
77
- # 'key' => Delegate.new(:r, :w, 'a default')}
73
+ # 'key' => Config.new(:r, :w, 'a default')}
78
74
  # b_configs = {
79
- # 'key' => Delegate.new(:r, :w, 'b default')}
80
- # 'a' => Delegate.new(:r, :w, DelegateHash.new(a_configs))}}
75
+ # 'key' => Config.new(:r, :w, 'b default')}
76
+ # 'a' => Config.new(:r, :w, ConfigHash.new(a_configs))}}
81
77
  #
82
78
  # Utils.dump_file(b_configs, 'b.yml')
83
79
  # File.read('b.yml') # => "key: b default"
@@ -93,28 +89,25 @@ module Configurable
93
89
  # preview dumps are always returned by dump_file.
94
90
  #
95
91
  # ==== Note
96
- # For load_file to correctly load a recursive dump, all delegate hashes
97
- # must use String keys. Symbol keys are allowed if the delegate hashes use
92
+ # For load_file to correctly load a recursive dump, all config hashes
93
+ # must use String keys. Symbol keys are allowed if the config hashes use
98
94
  # IndifferentAccess; all other keys will not load properly. By default
99
95
  # Configurable is set up to satisfy these conditions.
100
96
  #
101
97
  # 1.8 Bug: Currently dump_file with recurse=false will cause order to be
102
98
  # lost in nested configs. See http://bahuvrihi.lighthouseapp.com/projects/21202-configurable/tickets/8
103
- def dump_file(delegates, path, recurse=false, preview=false, &block)
104
- return dump_file(delegates, path, recurse, preview, &DEFAULT_DUMP) unless block_given?
99
+ def dump_file(configs, path, recurse=false, preview=false, &block)
100
+ return dump_file(configs, path, recurse, preview, &DEFAULT_DUMP) unless block_given?
105
101
 
106
102
  current = ""
107
103
  dumps = [[path, current]]
108
104
 
109
- dump(delegates, current) do |key, delegate|
110
- if recurse && delegate.is_nest?
111
- nested_delegates = delegate.default(false).delegates
112
- nested_dumps = dump_file(nested_delegates, recursive_path(key, path), true, true, &block)
113
-
114
- dumps.concat(nested_dumps)
105
+ dump(configs, current) do |key, config|
106
+ if recurse && config.kind_of?(NestConfig)
107
+ dumps.concat(dump_file(config.nest_class.configurations, recursive_path(key, path), true, true, &block))
115
108
  ""
116
109
  else
117
- yield(key, delegate)
110
+ yield(key, config)
118
111
  end
119
112
  end
120
113
 
@@ -8,7 +8,7 @@ module Configurable
8
8
 
9
9
  # Validation generates blocks for common validations and transformations of
10
10
  # configurations set through Configurable. In general these blocks load
11
- # string inputs as YAML and valdiate the results; non-string inputs are
11
+ # string inputs as YAML and validate the results; non-string inputs are
12
12
  # simply validated.
13
13
  #
14
14
  # integer = Validation.integer
@@ -56,7 +56,7 @@ module Configurable
56
56
 
57
57
  # Registers the default attributes with the specified block
58
58
  # in Configurable::DEFAULT_ATTRIBUTES.
59
- def register(block, attributes)
59
+ def register(attributes={}, &block)
60
60
  DEFAULT_ATTRIBUTES[block] = attributes
61
61
  block
62
62
  end
@@ -207,7 +207,7 @@ module Configurable
207
207
 
208
208
  # default attributes {:type => :string, :example => "string"}
209
209
  STRING = string_validation_block
210
- register STRING, :type => :string, :example => "string"
210
+ register :type => :string, :example => "string", &STRING
211
211
 
212
212
  # Same as string but allows nil. Note the special
213
213
  # behavior of the nil string '~' -- rather than
@@ -242,7 +242,7 @@ module Configurable
242
242
 
243
243
  # default attributes {:type => :symbol, :example => ":sym"}
244
244
  SYMBOL = yaml(Symbol)
245
- register SYMBOL, :type => :symbol, :example => ":sym"
245
+ register :type => :symbol, :example => ":sym", &SYMBOL
246
246
 
247
247
  # Same as symbol but allows nil:
248
248
  #
@@ -253,6 +253,46 @@ module Configurable
253
253
  SYMBOL_OR_NIL = yaml(Symbol, nil)
254
254
  register_as SYMBOL, SYMBOL_OR_NIL
255
255
 
256
+ # Returns a block that checks the input is a symbol.
257
+ # String inputs are directly converted to a symbol.
258
+ #
259
+ # strbol.class # => Proc
260
+ # strbol.call(:sym) # => :sym
261
+ # strbol.call(':sym') # => :":sym"
262
+ # strbol.call('str') # => :sym
263
+ # strbol.call(nil) # => ValidationError
264
+ #
265
+ def strbol(); STRBOL; end
266
+
267
+ # default attributes {:type => :symbol, :example => ":sym"}
268
+ STRBOL = lambda do |input|
269
+ if input.kind_of?(String)
270
+ input = input.to_sym
271
+ end
272
+
273
+ validate(input, [Symbol])
274
+ end
275
+ register :type => :symbol, :example => ":sym", &STRBOL
276
+
277
+ # Same as strbol but allows nil. Tilde is considered a string
278
+ # equivalent of nil (this behavior is consistent with the YAML
279
+ # methods but obviously inconsistent with the strbol behavior).
280
+ #
281
+ # strbol_or_nil.call('~') # => nil
282
+ # strbol_or_nil.call(nil) # => nil
283
+ def strbol_or_nil(); STRBOL_OR_NIL; end
284
+
285
+ STRBOL_OR_NIL = lambda do |input|
286
+ input = case input
287
+ when "~" then nil
288
+ when String then input.to_sym
289
+ else input
290
+ end
291
+
292
+ validate(input, [Symbol, nil])
293
+ end
294
+ register_as STRBOL, STRBOL_OR_NIL
295
+
256
296
  # Returns a block that checks the input is true, false or nil.
257
297
  # String inputs are loaded as yaml first.
258
298
  #
@@ -272,21 +312,21 @@ module Configurable
272
312
 
273
313
  # default attributes {:type => :boolean, :example => "true, yes"}
274
314
  BOOLEAN = yaml(true, false, nil)
275
- register BOOLEAN, :type => :boolean, :example => "true, yes"
315
+ register :type => :boolean, :example => "true, yes", &BOOLEAN
276
316
 
277
317
  # Same as boolean.
278
318
  def switch(); SWITCH; end
279
319
 
280
320
  # default attributes {:type => :switch}
281
321
  SWITCH = yaml(true, false, nil)
282
- register SWITCH, :type => :switch
322
+ register :type => :switch, &SWITCH
283
323
 
284
324
  # Same as boolean.
285
325
  def flag(); FLAG; end
286
326
 
287
327
  # default attributes {:type => :flag}
288
328
  FLAG = yaml(true, false, nil)
289
- register FLAG, :type => :flag
329
+ register :type => :flag, &FLAG
290
330
 
291
331
  # Returns a block that checks the input is an array.
292
332
  # String inputs are loaded as yaml first.
@@ -301,7 +341,7 @@ module Configurable
301
341
 
302
342
  # default attributes {:type => :array, :example => "[a, b, c]"}
303
343
  ARRAY = yaml(Array)
304
- register ARRAY, :type => :array, :example => "[a, b, c]"
344
+ register :type => :array, :example => "[a, b, c]", &ARRAY
305
345
 
306
346
  # Same as array but allows nil:
307
347
  #
@@ -343,7 +383,7 @@ module Configurable
343
383
 
344
384
  # default attributes {:type => :list, :split => ','}
345
385
  LIST = list_block
346
- register LIST, :type => :list, :split => ','
386
+ register :type => :list, :split => ',', &LIST
347
387
 
348
388
  # Returns a block that checks the input is a hash.
349
389
  # String inputs are loaded as yaml first.
@@ -358,7 +398,7 @@ module Configurable
358
398
 
359
399
  # default attributes {:type => :hash, :example => "{one: 1, two: 2}"}
360
400
  HASH = yaml(Hash)
361
- register HASH, :type => :hash, :example => "{one: 1, two: 2}"
401
+ register :type => :hash, :example => "{one: 1, two: 2}", &HASH
362
402
 
363
403
  # Same as hash but allows nil:
364
404
  #
@@ -383,7 +423,7 @@ module Configurable
383
423
 
384
424
  # default attributes {:type => :integer, :example => "2"}
385
425
  INTEGER = yaml(Integer)
386
- register INTEGER, :type => :integer, :example => "2"
426
+ register :type => :integer, :example => "2", &INTEGER
387
427
 
388
428
  # Same as integer but allows nil:
389
429
  #
@@ -409,7 +449,7 @@ module Configurable
409
449
 
410
450
  # default attributes {:type => :float, :example => "2.2, 2.0e+2"}
411
451
  FLOAT = yaml(Float)
412
- register FLOAT, :type => :float, :example => "2.2, 2.0e+2"
452
+ register :type => :float, :example => "2.2, 2.0e+2", &FLOAT
413
453
 
414
454
  # Same as float but allows nil:
415
455
  #
@@ -436,7 +476,7 @@ module Configurable
436
476
 
437
477
  # default attributes {:type => :numeric, :example => "2, 2.2, 2.0e+2"}
438
478
  NUMERIC = yaml(Numeric)
439
- register NUMERIC, :type => :numeric, :example => "2, 2.2, 2.0e+2"
479
+ register :type => :numeric, :example => "2, 2.2, 2.0e+2", &NUMERIC
440
480
 
441
481
  # Same as numeric but allows nil:
442
482
  #
@@ -477,7 +517,7 @@ module Configurable
477
517
 
478
518
  # default attributes {:type => :regexp, :example => "/regexp/i"}
479
519
  REGEXP = regexp_block
480
- register REGEXP, :type => :regexp, :example => "/regexp/i"
520
+ register :type => :regexp, :example => "/regexp/i", &REGEXP
481
521
 
482
522
  # Same as regexp but allows nil. Note the special behavior of the nil
483
523
  # string '~' -- rather than being converted to a regexp, it is processed
@@ -524,7 +564,7 @@ module Configurable
524
564
 
525
565
  # default attributes {:type => :range, :example => "min..max"}
526
566
  RANGE = range_block
527
- register RANGE, :type => :range, :example => "min..max"
567
+ register :type => :range, :example => "min..max", &RANGE
528
568
 
529
569
  # Same as range but allows nil:
530
570
  #
@@ -579,7 +619,7 @@ module Configurable
579
619
 
580
620
  # default attributes {:type => :time, :example => "2008-08-08 08:00:00"}
581
621
  TIME = time_block
582
- register TIME, :type => :time, :example => "2008-08-08 08:00:00"
622
+ register :type => :time, :example => "2008-08-08 08:00:00", &TIME
583
623
 
584
624
  # Same as time but allows nil:
585
625
  #
@@ -614,15 +654,14 @@ module Configurable
614
654
  # {:type => :select, :options => options}
615
655
  #
616
656
  def select(*options, &validation)
617
- block = lambda do |input|
657
+ register(
658
+ :type => :select,
659
+ :options => options,
660
+ :validation => attributes(validation)
661
+ ) do |input|
618
662
  input = validation.call(input) if validation
619
663
  validate(input, options)
620
664
  end
621
-
622
- register(block,
623
- :type => :select,
624
- :options => options,
625
- :validation => attributes(validation))
626
665
  end
627
666
 
628
667
  # Returns a block that checks the input is an array, and that each member
@@ -645,17 +684,16 @@ module Configurable
645
684
  # {:type => :list_select, :options => options, :split => ','}
646
685
  #
647
686
  def list_select(*options, &validation)
648
- block = lambda do |input|
687
+ register(
688
+ :type => :list_select,
689
+ :options => options,
690
+ :split => ',',
691
+ :validation => attributes(validation)
692
+ ) do |input|
649
693
  args = validate(input, [Array])
650
694
  args.collect! {|arg| validation.call(arg) } if validation
651
695
  args.each {|arg| validate(arg, options) }
652
696
  end
653
-
654
- register(block,
655
- :type => :list_select,
656
- :options => options,
657
- :split => ',',
658
- :validation => attributes(validation))
659
697
  end
660
698
 
661
699
  # Returns a block validating the input is an IO, a string, or an integer.
@@ -693,9 +731,9 @@ module Configurable
693
731
  end
694
732
  end
695
733
 
696
- # default attributes {:type => :io, :duplicate_default => false, :example => "/path/to/file"}
734
+ # default attributes {:type => :io, :dup => false, :example => "/path/to/file"}
697
735
  IO_OR_STRING = check(IO, String, Integer)
698
- register IO_OR_STRING, :type => :io, :duplicate_default => false, :example => "/path/to/file"
736
+ register :type => :io, :dup => false, :example => "/path/to/file", &IO_OR_STRING
699
737
 
700
738
  # Same as io but allows nil:
701
739
  #
@@ -0,0 +1,7 @@
1
+ module Configurable
2
+ MAJOR = 0
3
+ MINOR = 6
4
+ TINY = 0
5
+
6
+ VERSION="#{MAJOR}.#{MINOR}.#{TINY}"
7
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: configurable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Chiang
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-05-25 00:00:00 -06:00
12
+ date: 2009-12-05 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -20,7 +20,7 @@ dependencies:
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 0.9.0
23
+ version: 1.0.0
24
24
  version:
25
25
  description:
26
26
  email: simon.a.chiang@gmail.com
@@ -42,17 +42,22 @@ files:
42
42
  - lib/config_parser/utils.rb
43
43
  - lib/configurable.rb
44
44
  - lib/configurable/class_methods.rb
45
- - lib/configurable/delegate.rb
46
- - lib/configurable/delegate_hash.rb
45
+ - lib/configurable/config.rb
46
+ - lib/configurable/config_hash.rb
47
47
  - lib/configurable/indifferent_access.rb
48
48
  - lib/configurable/module_methods.rb
49
- - lib/configurable/validation.rb
49
+ - lib/configurable/nest_config.rb
50
+ - lib/configurable/ordered_hash_patch.rb
50
51
  - lib/configurable/utils.rb
52
+ - lib/configurable/validation.rb
53
+ - lib/configurable/version.rb
51
54
  - MIT-LICENSE
52
55
  - README
53
56
  - History
54
57
  has_rdoc: true
55
58
  homepage: http://tap.rubyforge.org/configurable
59
+ licenses: []
60
+
56
61
  post_install_message:
57
62
  rdoc_options:
58
63
  - --title
@@ -78,9 +83,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
83
  requirements: []
79
84
 
80
85
  rubyforge_project: tap
81
- rubygems_version: 1.3.1
86
+ rubygems_version: 1.3.5
82
87
  signing_key:
83
- specification_version: 2
88
+ specification_version: 3
84
89
  summary: configurable
85
90
  test_files: []
86
91
 
@@ -1,103 +0,0 @@
1
- module Configurable
2
-
3
- # Delegates are used by DelegateHash to determine how to map read/write
4
- # operations to a receiver.
5
- class Delegate
6
- class << self
7
-
8
- # Determines if the value is duplicable. Non-duplicable
9
- # values include nil, true, false, Symbol, Numeric, and
10
- # any object that does not respond to dup.
11
- def duplicable_value?(value)
12
- case value
13
- when nil, true, false, Symbol, Numeric, Method then false
14
- else value.respond_to?(:dup)
15
- end
16
- end
17
- end
18
-
19
- # The reader method, by default key
20
- attr_reader :reader
21
-
22
- # The writer method, by default key=
23
- attr_reader :writer
24
-
25
- # An hash of metadata for self, used to present the delegate in different
26
- # contexts (ex on the command line, in a web form, or a desktop app).
27
- # Note that attributes should be set through []= and not through this
28
- # reader.
29
- attr_reader :attributes
30
-
31
- # Initializes a new Delegate with the specified key and default value.
32
- def initialize(reader, writer="#{reader}=", default=nil, attributes={})
33
- @attributes = attributes
34
-
35
- self.default = default
36
- self.reader = reader
37
- self.writer = writer
38
- end
39
-
40
- # Sets the value of an attribute.
41
- def []=(key, value)
42
- attributes[key] = value
43
- reset_duplicable if key == :duplicate_default
44
- end
45
-
46
- # Returns the value for the specified attribute, or
47
- # default, if the attribute is unspecified.
48
- def [](key, default=nil)
49
- attributes.has_key?(key) ? attributes[key] : default
50
- end
51
-
52
- # Sets the default value for self.
53
- def default=(value)
54
- @default = value
55
- reset_duplicable
56
- end
57
-
58
- # Returns the default value, or a duplicate of the default value if specified.
59
- # The default value will not be duplicated unless duplicable (see
60
- # Delegate.duplicable_value?). Duplication can also be turned off by
61
- # specifying self[:duplicate_default] = false.
62
- def default(duplicate=true)
63
- duplicate && @duplicable ? @default.dup : @default
64
- end
65
-
66
- # Sets the reader for self.
67
- def reader=(value)
68
- raise ArgumentError, "reader may not be nil" if value == nil
69
- @reader = value.to_sym
70
- end
71
-
72
- # Sets the writer for self.
73
- def writer=(value)
74
- raise ArgumentError, "writer may not be nil" if value == nil
75
- @writer = value.to_sym
76
- end
77
-
78
- # Returns true if the default value is a kind of DelegateHash.
79
- def is_nest?
80
- @default.kind_of?(DelegateHash)
81
- end
82
-
83
- # True if another is a kind of Delegate with the same
84
- # reader, writer, and default value. Attributes are
85
- # not considered.
86
- def ==(another)
87
- another.kind_of?(Delegate) &&
88
- self.reader == another.reader &&
89
- self.writer == another.writer &&
90
- self.default(false) == another.default(false)
91
- end
92
-
93
- private
94
-
95
- # resets marker indiciating whether or not a default value is duplicable
96
- def reset_duplicable # :nodoc:
97
- @duplicable = case attributes[:duplicate_default]
98
- when true, nil then Delegate.duplicable_value?(@default)
99
- else false
100
- end
101
- end
102
- end
103
- end