configurable 0.7.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Help/Command Line.rdoc +141 -0
- data/Help/Config Syntax.rdoc +229 -0
- data/Help/Config Types.rdoc +143 -0
- data/{History → History.rdoc} +9 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +144 -0
- data/lib/configurable.rb +7 -270
- data/lib/configurable/class_methods.rb +344 -367
- data/lib/configurable/config_classes.rb +3 -0
- data/lib/configurable/config_classes/list_config.rb +26 -0
- data/lib/configurable/config_classes/nest_config.rb +50 -0
- data/lib/configurable/config_classes/scalar_config.rb +91 -0
- data/lib/configurable/config_hash.rb +87 -112
- data/lib/configurable/config_types.rb +6 -0
- data/lib/configurable/config_types/boolean_type.rb +22 -0
- data/lib/configurable/config_types/float_type.rb +11 -0
- data/lib/configurable/config_types/integer_type.rb +11 -0
- data/lib/configurable/config_types/nest_type.rb +39 -0
- data/lib/configurable/config_types/object_type.rb +58 -0
- data/lib/configurable/config_types/string_type.rb +15 -0
- data/lib/configurable/conversions.rb +91 -0
- data/lib/configurable/module_methods.rb +0 -1
- data/lib/configurable/version.rb +1 -5
- metadata +73 -30
- data/README +0 -207
- data/lib/cdoc.rb +0 -413
- data/lib/cdoc/cdoc_html_generator.rb +0 -38
- data/lib/cdoc/cdoc_html_template.rb +0 -42
- data/lib/config_parser.rb +0 -563
- data/lib/config_parser/option.rb +0 -108
- data/lib/config_parser/switch.rb +0 -44
- data/lib/config_parser/utils.rb +0 -177
- data/lib/configurable/config.rb +0 -97
- data/lib/configurable/indifferent_access.rb +0 -35
- data/lib/configurable/nest_config.rb +0 -78
- data/lib/configurable/ordered_hash_patch.rb +0 -85
- data/lib/configurable/utils.rb +0 -186
- data/lib/configurable/validation.rb +0 -768
@@ -0,0 +1,39 @@
|
|
1
|
+
module Configurable
|
2
|
+
module ConfigTypes
|
3
|
+
class NestType < ObjectType
|
4
|
+
class << self
|
5
|
+
def init(&block)
|
6
|
+
define_method(:init, &block) if block
|
7
|
+
self
|
8
|
+
end
|
9
|
+
end
|
10
|
+
matches Hash
|
11
|
+
|
12
|
+
attr_reader :configurable
|
13
|
+
|
14
|
+
def initialize(attrs={})
|
15
|
+
@configurable = attrs[:configurable]
|
16
|
+
|
17
|
+
unless configurable.respond_to?(:config) && configurable.class.respond_to?(:configs)
|
18
|
+
raise ArgumentError, "invalid configurable: #{configurable.inspect}"
|
19
|
+
end
|
20
|
+
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
def init(input)
|
25
|
+
obj = configurable.dup
|
26
|
+
obj.config.merge!(input)
|
27
|
+
obj
|
28
|
+
end
|
29
|
+
|
30
|
+
def cast(input)
|
31
|
+
configurable.class.configs.import(input)
|
32
|
+
end
|
33
|
+
|
34
|
+
def uncast(value)
|
35
|
+
configurable.class.configs.export(value)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Configurable
|
2
|
+
module ConfigTypes
|
3
|
+
class ObjectType
|
4
|
+
class << self
|
5
|
+
attr_reader :matchers
|
6
|
+
|
7
|
+
def inherited(base) # :nodoc:
|
8
|
+
unless base.instance_variable_defined?(:@matchers)
|
9
|
+
base.instance_variable_set(:@matchers, matchers.dup)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def subclass(*matchers, &caster)
|
14
|
+
subclass = Class.new(self)
|
15
|
+
subclass.matches(*matchers)
|
16
|
+
subclass.cast(&caster)
|
17
|
+
subclass
|
18
|
+
end
|
19
|
+
|
20
|
+
def cast(&block)
|
21
|
+
define_method(:cast, &block) if block
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def uncast(&block)
|
26
|
+
define_method(:uncast, &block) if block
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def errors(&block)
|
31
|
+
define_method(:errors, &block) if block
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def matches(*matchers)
|
36
|
+
@matchers = matchers
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
def matches?(value)
|
41
|
+
matchers.any? {|matcher| matcher === value }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
matches()
|
45
|
+
|
46
|
+
def initialize(attrs={})
|
47
|
+
end
|
48
|
+
|
49
|
+
def cast(input)
|
50
|
+
input
|
51
|
+
end
|
52
|
+
|
53
|
+
def uncast(value)
|
54
|
+
value
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'configurable/config_classes'
|
2
|
+
require 'config_parser'
|
3
|
+
|
4
|
+
module Configurable
|
5
|
+
|
6
|
+
# A set of methods used to convert various inputs based on a hash of (key,
|
7
|
+
# Config) pairs. Extend the hash and then use the methods.
|
8
|
+
module Conversions
|
9
|
+
include ConfigTypes
|
10
|
+
|
11
|
+
# Initializes and returns a ConfigParser generated using the configs for
|
12
|
+
# self. Arguments given to parser are passed to the ConfigParser
|
13
|
+
# initializer.
|
14
|
+
def to_parser(*args, &block)
|
15
|
+
parser = ConfigParser.new(*args, &block)
|
16
|
+
traverse do |nesting, config|
|
17
|
+
next if config[:hidden] == true || nesting.any? {|nest| nest[:hidden] == true }
|
18
|
+
|
19
|
+
nest_keys = nesting.collect {|nest| nest.key }
|
20
|
+
long, short = nesting.collect {|nest| nest.name }.push(config.name).join(':'), nil
|
21
|
+
long, short = short, long if long.length == 1
|
22
|
+
|
23
|
+
guess_attrs = {
|
24
|
+
:long => long,
|
25
|
+
:short => short
|
26
|
+
}
|
27
|
+
|
28
|
+
config_attrs = {
|
29
|
+
:key => config.key,
|
30
|
+
:nest_keys => nest_keys,
|
31
|
+
:default => config.default,
|
32
|
+
:callback => lambda {|value| config.type.cast(value) }
|
33
|
+
}
|
34
|
+
|
35
|
+
attrs = guess_attrs.merge(config.metadata).merge(config_attrs)
|
36
|
+
parser.on(attrs)
|
37
|
+
end
|
38
|
+
|
39
|
+
parser.sort_opts!
|
40
|
+
parser
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns a hash of the default values for each config in self.
|
44
|
+
def to_default
|
45
|
+
default = {}
|
46
|
+
each_pair do |key, config|
|
47
|
+
default[key] = config.default
|
48
|
+
end
|
49
|
+
default
|
50
|
+
end
|
51
|
+
|
52
|
+
def import(source, target={})
|
53
|
+
each_value do |config|
|
54
|
+
name = config.name
|
55
|
+
|
56
|
+
if source.has_key?(name)
|
57
|
+
target[config.key] = config.cast(source[name])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
target
|
62
|
+
end
|
63
|
+
|
64
|
+
def export(source, target={})
|
65
|
+
each_value do |config|
|
66
|
+
key = config.key
|
67
|
+
|
68
|
+
if source.has_key?(key)
|
69
|
+
target[config.name] = config.uncast(source[key])
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
target
|
74
|
+
end
|
75
|
+
|
76
|
+
# Yields each config in configs to the block with nesting, after appened
|
77
|
+
# self to nesting.
|
78
|
+
def traverse(nesting=[], &block)
|
79
|
+
each_value do |config|
|
80
|
+
if config.type.kind_of?(NestType)
|
81
|
+
nesting.push config
|
82
|
+
configs = config.type.configurable.class.configs
|
83
|
+
configs.traverse(nesting, &block)
|
84
|
+
nesting.pop
|
85
|
+
else
|
86
|
+
yield(nesting, config)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/lib/configurable/version.rb
CHANGED
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: configurable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 23
|
5
|
+
prerelease:
|
5
6
|
segments:
|
7
|
+
- 1
|
6
8
|
- 0
|
7
|
-
- 7
|
8
9
|
- 0
|
9
|
-
version: 0.
|
10
|
+
version: 1.0.0
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Simon Chiang
|
@@ -14,63 +15,101 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date:
|
18
|
+
date: 2011-07-12 00:00:00 -06:00
|
18
19
|
default_executable:
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
21
22
|
name: lazydoc
|
22
23
|
prerelease: false
|
23
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
24
26
|
requirements:
|
25
|
-
- -
|
27
|
+
- - ~>
|
26
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 15
|
27
30
|
segments:
|
28
31
|
- 1
|
29
32
|
- 0
|
30
|
-
|
31
|
-
version: 1.0.0
|
33
|
+
version: "1.0"
|
32
34
|
type: :runtime
|
33
35
|
version_requirements: *id001
|
34
|
-
|
35
|
-
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: config_parser
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 3
|
45
|
+
segments:
|
46
|
+
- 0
|
47
|
+
- 5
|
48
|
+
- 4
|
49
|
+
version: 0.5.4
|
50
|
+
type: :runtime
|
51
|
+
version_requirements: *id002
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
name: bundler
|
54
|
+
prerelease: false
|
55
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ~>
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 15
|
61
|
+
segments:
|
62
|
+
- 1
|
63
|
+
- 0
|
64
|
+
version: "1.0"
|
65
|
+
type: :development
|
66
|
+
version_requirements: *id003
|
67
|
+
description: Configurable adds methods to declare class configurations. Configurations are inheritable, delegate to methods, and have hash-like access. Configurable constructs configs such that they easily map to config files, web forms, and the command line.
|
68
|
+
email:
|
69
|
+
- simon.a.chiang@gmail.com
|
36
70
|
executables: []
|
37
71
|
|
38
72
|
extensions: []
|
39
73
|
|
40
74
|
extra_rdoc_files:
|
41
75
|
- MIT-LICENSE
|
42
|
-
- README
|
43
|
-
- History
|
76
|
+
- README.rdoc
|
77
|
+
- History.rdoc
|
78
|
+
- Help/Command Line.rdoc
|
79
|
+
- Help/Config Syntax.rdoc
|
80
|
+
- Help/Config Types.rdoc
|
44
81
|
files:
|
45
|
-
- lib/cdoc.rb
|
46
|
-
- lib/cdoc/cdoc_html_generator.rb
|
47
|
-
- lib/cdoc/cdoc_html_template.rb
|
48
|
-
- lib/config_parser.rb
|
49
|
-
- lib/config_parser/option.rb
|
50
|
-
- lib/config_parser/switch.rb
|
51
|
-
- lib/config_parser/utils.rb
|
52
82
|
- lib/configurable.rb
|
53
83
|
- lib/configurable/class_methods.rb
|
54
|
-
- lib/configurable/
|
84
|
+
- lib/configurable/config_classes.rb
|
85
|
+
- lib/configurable/config_classes/list_config.rb
|
86
|
+
- lib/configurable/config_classes/nest_config.rb
|
87
|
+
- lib/configurable/config_classes/scalar_config.rb
|
55
88
|
- lib/configurable/config_hash.rb
|
56
|
-
- lib/configurable/
|
89
|
+
- lib/configurable/config_types.rb
|
90
|
+
- lib/configurable/config_types/boolean_type.rb
|
91
|
+
- lib/configurable/config_types/float_type.rb
|
92
|
+
- lib/configurable/config_types/integer_type.rb
|
93
|
+
- lib/configurable/config_types/nest_type.rb
|
94
|
+
- lib/configurable/config_types/object_type.rb
|
95
|
+
- lib/configurable/config_types/string_type.rb
|
96
|
+
- lib/configurable/conversions.rb
|
57
97
|
- lib/configurable/module_methods.rb
|
58
|
-
- lib/configurable/nest_config.rb
|
59
|
-
- lib/configurable/ordered_hash_patch.rb
|
60
|
-
- lib/configurable/utils.rb
|
61
|
-
- lib/configurable/validation.rb
|
62
98
|
- lib/configurable/version.rb
|
63
99
|
- MIT-LICENSE
|
64
|
-
- README
|
65
|
-
- History
|
100
|
+
- README.rdoc
|
101
|
+
- History.rdoc
|
102
|
+
- Help/Command Line.rdoc
|
103
|
+
- Help/Config Syntax.rdoc
|
104
|
+
- Help/Config Types.rdoc
|
66
105
|
has_rdoc: true
|
67
|
-
homepage: http://
|
106
|
+
homepage: http://github.com/thinkerbot/configurable
|
68
107
|
licenses: []
|
69
108
|
|
70
109
|
post_install_message:
|
71
110
|
rdoc_options:
|
72
111
|
- --main
|
73
|
-
- README
|
112
|
+
- README.rdoc
|
74
113
|
- -S
|
75
114
|
- -N
|
76
115
|
- --title
|
@@ -78,23 +117,27 @@ rdoc_options:
|
|
78
117
|
require_paths:
|
79
118
|
- lib
|
80
119
|
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
+
none: false
|
81
121
|
requirements:
|
82
122
|
- - ">="
|
83
123
|
- !ruby/object:Gem::Version
|
124
|
+
hash: 3
|
84
125
|
segments:
|
85
126
|
- 0
|
86
127
|
version: "0"
|
87
128
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
88
130
|
requirements:
|
89
131
|
- - ">="
|
90
132
|
- !ruby/object:Gem::Version
|
133
|
+
hash: 3
|
91
134
|
segments:
|
92
135
|
- 0
|
93
136
|
version: "0"
|
94
137
|
requirements: []
|
95
138
|
|
96
|
-
rubyforge_project:
|
97
|
-
rubygems_version: 1.
|
139
|
+
rubyforge_project:
|
140
|
+
rubygems_version: 1.6.2
|
98
141
|
signing_key:
|
99
142
|
specification_version: 3
|
100
143
|
summary: configurable
|
data/README
DELETED
@@ -1,207 +0,0 @@
|
|
1
|
-
= Configurable[http://tap.rubyforge.org/configurable]
|
2
|
-
|
3
|
-
Class configurations that map to the command line.
|
4
|
-
|
5
|
-
== Description
|
6
|
-
|
7
|
-
Configurable allows the declaration of class configurations. Configurations
|
8
|
-
are inheritable, delegate to methods, and have hash-like access. Configurable
|
9
|
-
maps configurations to the command line through ConfigParser and is used by
|
10
|
-
the Tap[http://tap.rubyforge.org] framework.
|
11
|
-
|
12
|
-
Check out these links for development and bug tracking.
|
13
|
-
|
14
|
-
* Website[http://tap.rubyforge.org/configurable]
|
15
|
-
* Github[http://github.com/bahuvrihi/configurable/tree/master]
|
16
|
-
* {Google Group}[http://groups.google.com/group/ruby-on-tap]
|
17
|
-
|
18
|
-
==== Minimal Example
|
19
|
-
|
20
|
-
Include Configurable and declare configurations using the config method.
|
21
|
-
Configs now have accessors and initialize with the default value.
|
22
|
-
|
23
|
-
class ConfigClass
|
24
|
-
include Configurable
|
25
|
-
config :key, 'default', :short => 'k' # a sample config
|
26
|
-
end
|
27
|
-
|
28
|
-
c = ConfigClass.new
|
29
|
-
c.key # => 'default'
|
30
|
-
c.key = 'new value'
|
31
|
-
c.config[:key] # => 'new value'
|
32
|
-
|
33
|
-
Use a ConfigParser to parse configurations from the command line. Non-class
|
34
|
-
options may be defined with (mostly) the same syntax as {OptionParser}[http://www.ruby-doc.org/core/classes/OptionParser.html]:
|
35
|
-
|
36
|
-
parser = ConfigParser.new
|
37
|
-
|
38
|
-
# add class configurations
|
39
|
-
parser.add(ConfigClass.configurations)
|
40
|
-
|
41
|
-
# define an option a-la OptionParser
|
42
|
-
parser.on '-s', '--long ARGUMENT', 'description' do |value|
|
43
|
-
parser[:long] = value
|
44
|
-
end
|
45
|
-
|
46
|
-
parser.parse "one two --key value -s VALUE three"
|
47
|
-
# => ['one', 'two', 'three']
|
48
|
-
|
49
|
-
parser.config
|
50
|
-
# => {
|
51
|
-
# :key => 'value',
|
52
|
-
# :long => 'VALUE'
|
53
|
-
# }
|
54
|
-
|
55
|
-
"\n" + parser.to_s
|
56
|
-
# => %Q{
|
57
|
-
# -k, --key KEY a sample config
|
58
|
-
# -s, --long ARGUMENT description
|
59
|
-
# }
|
60
|
-
|
61
|
-
== Usage
|
62
|
-
|
63
|
-
The config method is used to declare class configurations. A block may be
|
64
|
-
provided to validate/transform inputs; many standard validations are available
|
65
|
-
through the 'c' method (an alias for the
|
66
|
-
{Validation}[link:classes/Configurable/Validation.html] module).
|
67
|
-
|
68
|
-
class ConfigClass
|
69
|
-
include Configurable
|
70
|
-
|
71
|
-
# basic #
|
72
|
-
|
73
|
-
config :key, 'default' # a simple config
|
74
|
-
config :flag, false, &c.flag # a flag config
|
75
|
-
config :switch, false, &c.switch # a --[no-]switch config
|
76
|
-
config :num, 10, &c.integer # integer only
|
77
|
-
|
78
|
-
# fancy #
|
79
|
-
|
80
|
-
config :range, 1..10, &c.range # specifies a range
|
81
|
-
config :select, 'a', &c.select('a','b') # value must be 'a' or 'b'
|
82
|
-
config :list, [], &c.list # allows a list of entries
|
83
|
-
|
84
|
-
# custom #
|
85
|
-
|
86
|
-
config :upcase, 'default' do |value| # custom transformation
|
87
|
-
value.upcase
|
88
|
-
end
|
89
|
-
|
90
|
-
config :alt, 'default', # alternative flags
|
91
|
-
:short => 's',
|
92
|
-
:long => 'long',
|
93
|
-
:arg_name => 'CUSTOM'
|
94
|
-
|
95
|
-
# Initializes a new instance, setting the overriding configs.
|
96
|
-
def initialize(config={})
|
97
|
-
initialize_config(config)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
ConfigParser uses the config declarations to parse configurations and to make
|
102
|
-
a documented help string:
|
103
|
-
|
104
|
-
parser = ConfigParser.new
|
105
|
-
parser.add(ConfigClass.configurations)
|
106
|
-
|
107
|
-
parser.parse "a b --key=value --flag --no-switch --num 8 c"
|
108
|
-
# => ['a', 'b', 'c']
|
109
|
-
|
110
|
-
parser.config
|
111
|
-
# => {
|
112
|
-
# :key => 'value',
|
113
|
-
# :flag => true,
|
114
|
-
# :switch => false,
|
115
|
-
# :num => '8',
|
116
|
-
# :range => 1..10,
|
117
|
-
# :select => 'a',
|
118
|
-
# :list => [],
|
119
|
-
# :upcase => 'default',
|
120
|
-
# :alt => 'default'
|
121
|
-
# }
|
122
|
-
|
123
|
-
"\n" + parser.to_s
|
124
|
-
# => %Q{
|
125
|
-
# --key KEY a simple config
|
126
|
-
# --flag a flag config
|
127
|
-
# --[no-]switch a --[no-]switch config
|
128
|
-
# --num NUM integer only
|
129
|
-
# --range RANGE specifies a range
|
130
|
-
# --select SELECT value must be 'a' or 'b'
|
131
|
-
# --list LIST allows a list of entries
|
132
|
-
# --upcase UPCASE custom transformation
|
133
|
-
# -s, --long CUSTOM alternative flags
|
134
|
-
# }
|
135
|
-
|
136
|
-
Configurable classes typically call initialize_config to set configurations
|
137
|
-
during initialization. The validation/transformation blocks are called as
|
138
|
-
configurations are set. Notice how the :num and :upcase configs are translated
|
139
|
-
on the instance:
|
140
|
-
|
141
|
-
c = ConfigClass.new(parser.config)
|
142
|
-
c.config.to_hash
|
143
|
-
# => {
|
144
|
-
# :key => 'value',
|
145
|
-
# :flag => true,
|
146
|
-
# :switch => false,
|
147
|
-
# :num => 8, # no longer a string
|
148
|
-
# :range => 1..10,
|
149
|
-
# :select => 'a',
|
150
|
-
# :list => [],
|
151
|
-
# :upcase => 'DEFAULT', # no longer downcase
|
152
|
-
# :alt => 'default'
|
153
|
-
# }
|
154
|
-
|
155
|
-
Configurations automatically generate accessors (the blocks are basically
|
156
|
-
writer methods), and may be accessed through the config object. Configurations
|
157
|
-
are validated every time they are set, regardless of whether they are set
|
158
|
-
through an accessor or config.
|
159
|
-
|
160
|
-
c.upcase # => 'DEFAULT'
|
161
|
-
|
162
|
-
c.config[:upcase] = 'neW valuE'
|
163
|
-
c.upcase # => 'NEW VALUE'
|
164
|
-
|
165
|
-
c.upcase = 'fiNal Value'
|
166
|
-
c.config[:upcase] # => 'FINAL VALUE'
|
167
|
-
|
168
|
-
c.select = 'b' # ok
|
169
|
-
c.select = 'c' # !> ValidationError
|
170
|
-
c.config[:select] = 'c' # !> ValidationError
|
171
|
-
|
172
|
-
By default config treats string and symbol keys identically, making YAML an
|
173
|
-
obvious choice for configuration files.
|
174
|
-
|
175
|
-
yaml_str = %Q{
|
176
|
-
key: a new value
|
177
|
-
flag: false
|
178
|
-
range: 1..100
|
179
|
-
}
|
180
|
-
|
181
|
-
c.reconfigure(YAML.load(yaml_str))
|
182
|
-
c.config.to_hash
|
183
|
-
# => {
|
184
|
-
# :key => 'a new value',
|
185
|
-
# :flag => false,
|
186
|
-
# :switch => false,
|
187
|
-
# :num => 8,
|
188
|
-
# :range => 1..100,
|
189
|
-
# :select => 'b',
|
190
|
-
# :list => [],
|
191
|
-
# :upcase => 'FINAL VALUE',
|
192
|
-
# :alt => 'default'
|
193
|
-
# }
|
194
|
-
|
195
|
-
See the Configurable module for more details.
|
196
|
-
|
197
|
-
== Installation
|
198
|
-
|
199
|
-
Configurable is available as a gem on Gemcutter[http://gemcutter.org/gems/configurable].
|
200
|
-
|
201
|
-
% gem install configurable
|
202
|
-
|
203
|
-
== Info
|
204
|
-
|
205
|
-
Developer:: {Simon Chiang}[http://bahuvrihi.wordpress.com]
|
206
|
-
License:: {MIT-Style}[link:files/MIT-LICENSE.html]
|
207
|
-
|