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.
- data/History +19 -0
- data/MIT-LICENSE +17 -15
- data/README +112 -40
- data/lib/config_parser.rb +159 -96
- data/lib/config_parser/option.rb +10 -3
- data/lib/config_parser/switch.rb +1 -1
- data/lib/config_parser/utils.rb +52 -18
- data/lib/configurable.rb +128 -36
- data/lib/configurable/class_methods.rb +171 -192
- data/lib/configurable/config.rb +97 -0
- data/lib/configurable/config_hash.rb +198 -0
- data/lib/configurable/indifferent_access.rb +1 -1
- data/lib/configurable/module_methods.rb +7 -17
- data/lib/configurable/nest_config.rb +78 -0
- data/lib/configurable/ordered_hash_patch.rb +85 -0
- data/lib/configurable/utils.rb +25 -32
- data/lib/configurable/validation.rb +69 -31
- data/lib/configurable/version.rb +7 -0
- metadata +13 -8
- data/lib/configurable/delegate.rb +0 -103
- data/lib/configurable/delegate_hash.rb +0 -226
    
        data/lib/configurable/utils.rb
    CHANGED
    
    | @@ -1,16 +1,12 @@ | |
| 1 1 | 
             
            module Configurable
         | 
| 2 2 |  | 
| 3 | 
            -
              # Utility methods to dump and load  | 
| 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,  | 
| 9 | 
            -
                  default = delegate.default(false)
         | 
| 10 | 
            -
                  
         | 
| 7 | 
            +
                default_dump_block = lambda do |key, config|
         | 
| 11 8 | 
             
                  # note: this causes order to be lost...
         | 
| 12 | 
            -
                   | 
| 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  | 
| 27 | 
            -
                # symbol keys are be stringified if  | 
| 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,  | 
| 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( | 
| 61 | 
            -
                  return dump( | 
| 56 | 
            +
                def dump(configs, target="")
         | 
| 57 | 
            +
                  return dump(configs, target, &DEFAULT_DUMP) unless block_given?
         | 
| 62 58 |  | 
| 63 | 
            -
                  stringify =  | 
| 64 | 
            -
                   | 
| 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,  | 
| 62 | 
            +
                    target << yield(key, config)
         | 
| 67 63 | 
             
                  end
         | 
| 68 64 |  | 
| 69 65 | 
             
                  target
         | 
| 70 66 | 
             
                end
         | 
| 71 67 |  | 
| 72 | 
            -
                # Dumps the  | 
| 73 | 
            -
                #  | 
| 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' =>  | 
| 73 | 
            +
                #     'key' => Config.new(:r, :w, 'a default')}
         | 
| 78 74 | 
             
                #   b_configs = {
         | 
| 79 | 
            -
                #     'key' =>  | 
| 80 | 
            -
                #     'a' =>  | 
| 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  | 
| 97 | 
            -
                # must use String keys.  Symbol keys are allowed if the  | 
| 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( | 
| 104 | 
            -
                  return dump_file( | 
| 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( | 
| 110 | 
            -
                    if recurse &&  | 
| 111 | 
            -
                       | 
| 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,  | 
| 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  | 
| 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( | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 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  | 
| 520 | 
            +
                register :type => :regexp, :example => "/regexp/i", ®EXP
         | 
| 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  | 
| 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  | 
| 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 | 
            -
                   | 
| 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 | 
            -
                   | 
| 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, : | 
| 734 | 
            +
                # default attributes {:type => :io, :dup => false, :example => "/path/to/file"}
         | 
| 697 735 | 
             
                IO_OR_STRING = check(IO, String, Integer)
         | 
| 698 | 
            -
                register  | 
| 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 | 
             
                #
         | 
    
        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. | 
| 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 | 
| 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. | 
| 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/ | 
| 46 | 
            -
            - lib/configurable/ | 
| 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/ | 
| 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. | 
| 86 | 
            +
            rubygems_version: 1.3.5
         | 
| 82 87 | 
             
            signing_key: 
         | 
| 83 | 
            -
            specification_version:  | 
| 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
         |