parameters 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog.md +5 -0
- data/lib/parameters/class_methods.rb +30 -6
- data/lib/parameters/class_param.rb +2 -2
- data/lib/parameters/instance_param.rb +4 -2
- data/lib/parameters/module_methods.rb +28 -0
- data/lib/parameters/options.rb +222 -0
- data/lib/parameters/param.rb +4 -2
- data/lib/parameters/parameters.rb +41 -3
- data/lib/parameters/types/array.rb +28 -0
- data/lib/parameters/types/hash.rb +44 -1
- data/lib/parameters/types/type.rb +52 -0
- data/lib/parameters/version.rb +1 -1
- data/spec/classes/option_parameters.rb +30 -0
- data/spec/options_spec.rb +142 -0
- data/spec/parameters_spec.rb +26 -2
- data/spec/types/array_spec.rb +11 -2
- data/spec/types/hash_spec.rb +20 -4
- data/spec/types/set_spec.rb +11 -2
- metadata +13 -8
data/ChangeLog.md
CHANGED
@@ -4,16 +4,14 @@ require 'parameters/extensions/meta'
|
|
4
4
|
|
5
5
|
module Parameters
|
6
6
|
module ClassMethods
|
7
|
-
def included(base)
|
8
|
-
base.extend ClassMethods
|
9
|
-
end
|
10
|
-
|
11
7
|
#
|
12
8
|
# @return [Hash]
|
13
9
|
# Parameters for the class.
|
14
10
|
#
|
11
|
+
# @api semipublic
|
12
|
+
#
|
15
13
|
def params
|
16
|
-
@
|
14
|
+
@parameters ||= {}
|
17
15
|
end
|
18
16
|
|
19
17
|
#
|
@@ -26,6 +24,8 @@ module Parameters
|
|
26
24
|
# Test.params = {:x => 5, :y => 2}
|
27
25
|
# # => {:x=>5, :y=>2}
|
28
26
|
#
|
27
|
+
# @api semipublic
|
28
|
+
#
|
29
29
|
def params=(values)
|
30
30
|
values.each do |name,value|
|
31
31
|
if has_param?(name)
|
@@ -64,6 +64,8 @@ module Parameters
|
|
64
64
|
# @example
|
65
65
|
# parameter 'var', :default => 3, :description => 'my variable'
|
66
66
|
#
|
67
|
+
# @api public
|
68
|
+
#
|
67
69
|
def parameter(name,options={})
|
68
70
|
name = name.to_sym
|
69
71
|
|
@@ -77,6 +79,11 @@ module Parameters
|
|
77
79
|
get_param(name).value = value
|
78
80
|
end
|
79
81
|
|
82
|
+
# define the ? method, to determine if the parameter is set
|
83
|
+
meta_def("#{name}?") do
|
84
|
+
!!get_param(name).value
|
85
|
+
end
|
86
|
+
|
80
87
|
# define the reader instance methods for the parameter
|
81
88
|
define_method(name) do
|
82
89
|
get_param(name).value
|
@@ -87,6 +94,11 @@ module Parameters
|
|
87
94
|
get_param(name).value = value
|
88
95
|
end
|
89
96
|
|
97
|
+
# define the ? method, to determine if the parameter is set
|
98
|
+
define_method("#{name}?") do
|
99
|
+
!!get_param(name).value
|
100
|
+
end
|
101
|
+
|
90
102
|
# create the new parameter
|
91
103
|
new_param = Parameters::ClassParam.new(
|
92
104
|
name,
|
@@ -107,6 +119,8 @@ module Parameters
|
|
107
119
|
# Specifies whether or not there is a class parameter with the
|
108
120
|
# specified name.
|
109
121
|
#
|
122
|
+
# @api semipublic
|
123
|
+
#
|
110
124
|
def has_param?(name)
|
111
125
|
name = name.to_sym
|
112
126
|
|
@@ -131,6 +145,8 @@ module Parameters
|
|
131
145
|
# @raise [ParamNotFound]
|
132
146
|
# No class parameter with the specified name could be found.
|
133
147
|
#
|
148
|
+
# @api semipublic
|
149
|
+
#
|
134
150
|
def get_param(name)
|
135
151
|
name = name.to_sym
|
136
152
|
|
@@ -162,6 +178,8 @@ module Parameters
|
|
162
178
|
#
|
163
179
|
# @since 0.3.0
|
164
180
|
#
|
181
|
+
# @api semipublic
|
182
|
+
#
|
165
183
|
def set_param(name,value)
|
166
184
|
name = name.to_sym
|
167
185
|
|
@@ -182,8 +200,10 @@ module Parameters
|
|
182
200
|
# @yield [param]
|
183
201
|
# The block that will be passed each class parameter.
|
184
202
|
#
|
203
|
+
# @api semipublic
|
204
|
+
#
|
185
205
|
def each_param(&block)
|
186
|
-
ancestors.
|
206
|
+
ancestors.reverse_each do |ancestor|
|
187
207
|
if ancestor.included_modules.include?(Parameters)
|
188
208
|
ancestor.params.each_value(&block)
|
189
209
|
end
|
@@ -201,6 +221,8 @@ module Parameters
|
|
201
221
|
# @raise [ParamNotFound]
|
202
222
|
# No class parameter with the specified name could be found.
|
203
223
|
#
|
224
|
+
# @api semipublic
|
225
|
+
#
|
204
226
|
def describe_param(name)
|
205
227
|
get_param(name).description
|
206
228
|
end
|
@@ -214,6 +236,8 @@ module Parameters
|
|
214
236
|
# @raise [ParamNotFound]
|
215
237
|
# No class parameter with the specified name could be found.
|
216
238
|
#
|
239
|
+
# @api semipublic
|
240
|
+
#
|
217
241
|
def param_value(name)
|
218
242
|
get_param(name).value
|
219
243
|
end
|
@@ -72,8 +72,8 @@ module Parameters
|
|
72
72
|
def to_s
|
73
73
|
text = @name.to_s
|
74
74
|
|
75
|
-
text << "
|
76
|
-
text << "\t#{@description}"
|
75
|
+
text << "\t[#{@value.inspect}]" if @value
|
76
|
+
text << "\t#{@description}" if @description
|
77
77
|
|
78
78
|
return text
|
79
79
|
end
|
@@ -25,6 +25,8 @@ module Parameters
|
|
25
25
|
# @param [Object] value
|
26
26
|
# The initial value for the instance parameter.
|
27
27
|
#
|
28
|
+
# @api semipublic
|
29
|
+
#
|
28
30
|
def initialize(object,name,type=nil,description=nil,value=nil)
|
29
31
|
super(name,type,description)
|
30
32
|
|
@@ -76,8 +78,8 @@ module Parameters
|
|
76
78
|
def to_s
|
77
79
|
text = @name.to_s
|
78
80
|
|
79
|
-
text << "
|
80
|
-
text << "\t#{@description}"
|
81
|
+
text << "\t[#{value.inspect}]" if value
|
82
|
+
text << "\t#{@description}" if @description
|
81
83
|
|
82
84
|
return text
|
83
85
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'parameters/class_methods'
|
2
|
+
|
3
|
+
module Parameters
|
4
|
+
module ModuleMethods
|
5
|
+
#
|
6
|
+
# Ensures that the module will re-extend Parameters::ClassMethods,
|
7
|
+
# when included.
|
8
|
+
#
|
9
|
+
def included(base)
|
10
|
+
base.extend ClassMethods
|
11
|
+
|
12
|
+
if base.kind_of?(Module)
|
13
|
+
# re-extend the ModuleMethods
|
14
|
+
base.extend ModuleMethods
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# Ensures that the module will initialize parameters, when extended
|
20
|
+
# into an Object.
|
21
|
+
#
|
22
|
+
def extended(object)
|
23
|
+
each_param do |param|
|
24
|
+
object.params[param.name] = param.to_instance(object)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,222 @@
|
|
1
|
+
require 'parameters/param'
|
2
|
+
require 'parameters/types'
|
3
|
+
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
module Parameters
|
7
|
+
#
|
8
|
+
# @since 0.4.0
|
9
|
+
#
|
10
|
+
module Options
|
11
|
+
# The usage messages for various Parameter {Types}.
|
12
|
+
USAGES = {
|
13
|
+
Types::Integer => 'NUM',
|
14
|
+
Types::Float => 'DEC',
|
15
|
+
Types::Symbol => 'NAME',
|
16
|
+
Types::Time => 'TIME',
|
17
|
+
Types::DateTime => 'DATE|TIME',
|
18
|
+
Types::Date => 'DATE',
|
19
|
+
Types::Regexp => 'REGEXP',
|
20
|
+
Types::URI => 'URI',
|
21
|
+
Types::Array => 'VALUE [...]',
|
22
|
+
Types::Set => 'VALUE [...]',
|
23
|
+
Types::Hash => 'NAME:VALUE [...]'
|
24
|
+
}
|
25
|
+
|
26
|
+
# The OptionParser acceptance classes for various Parameter {Types}.
|
27
|
+
ACCEPTS = {
|
28
|
+
Types::Object => Object,
|
29
|
+
Types::Boolean => TrueClass,
|
30
|
+
Types::Integer => Integer,
|
31
|
+
Types::Float => Float,
|
32
|
+
Types::Symbol => Symbol,
|
33
|
+
Types::String => String,
|
34
|
+
Types::Time => String,
|
35
|
+
Types::DateTime => String,
|
36
|
+
Types::Date => String,
|
37
|
+
Types::URI => String
|
38
|
+
}
|
39
|
+
|
40
|
+
#
|
41
|
+
# Returns the option flag for the given parameter.
|
42
|
+
#
|
43
|
+
# @param [Param] param
|
44
|
+
# The parameter.
|
45
|
+
#
|
46
|
+
# @return [String]
|
47
|
+
# The option flag.
|
48
|
+
#
|
49
|
+
# @api semipublic
|
50
|
+
#
|
51
|
+
def self.flag(param)
|
52
|
+
name = param.name.to_s.gsub('_','-')
|
53
|
+
|
54
|
+
if param.type == Types::Boolean
|
55
|
+
"--[no-]#{name}"
|
56
|
+
else
|
57
|
+
"--#{name}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Returns the Usage String for the parameter.
|
63
|
+
#
|
64
|
+
# @param [Param] param
|
65
|
+
# The parameter.
|
66
|
+
#
|
67
|
+
# @return [String]
|
68
|
+
# The Usage String.
|
69
|
+
#
|
70
|
+
# @api semipublic
|
71
|
+
#
|
72
|
+
def self.usage(param)
|
73
|
+
name = param.name.to_s
|
74
|
+
|
75
|
+
type_usage = lambda { |type|
|
76
|
+
if type.class == Types::Hash
|
77
|
+
type_usage[type.key_type] + ':' +
|
78
|
+
type_usage[type.value_type] + ' [...]'
|
79
|
+
elsif type.class <= Types::Array
|
80
|
+
type_usage[type.element_type] + ' [...]'
|
81
|
+
elsif (type == Types::String) ||
|
82
|
+
(type == Types::Object)
|
83
|
+
name.upcase
|
84
|
+
else
|
85
|
+
USAGES[type]
|
86
|
+
end
|
87
|
+
}
|
88
|
+
|
89
|
+
return type_usage[param.type]
|
90
|
+
end
|
91
|
+
|
92
|
+
#
|
93
|
+
# Returns the OptionParser acceptance class for the parameter.
|
94
|
+
#
|
95
|
+
# @param [Param] param
|
96
|
+
# The parameter.
|
97
|
+
#
|
98
|
+
# @return [Class]
|
99
|
+
# The acceptance class.
|
100
|
+
#
|
101
|
+
# @api semipublic
|
102
|
+
#
|
103
|
+
def self.accepts(param)
|
104
|
+
type = param.type
|
105
|
+
|
106
|
+
if type <= Types::Hash
|
107
|
+
Hash
|
108
|
+
elsif type <= Types::Array
|
109
|
+
Array
|
110
|
+
else
|
111
|
+
ACCEPTS[type]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
#
|
116
|
+
# Defines an option for the parameter.
|
117
|
+
#
|
118
|
+
# @param [OptionParser] opts
|
119
|
+
# The option parser.
|
120
|
+
#
|
121
|
+
# @param [Param] param
|
122
|
+
# The parameter.
|
123
|
+
#
|
124
|
+
# @param [Hash] options
|
125
|
+
# Additional options for the option.
|
126
|
+
#
|
127
|
+
# @option options [String] :flag
|
128
|
+
# The short flag for the option.
|
129
|
+
#
|
130
|
+
# @option options [String] :usage
|
131
|
+
# The USAGE String for the option.
|
132
|
+
#
|
133
|
+
# @api public
|
134
|
+
#
|
135
|
+
def self.define(opts,param,options={})
|
136
|
+
short_flag = options[:flag]
|
137
|
+
long_flag = flag(param)
|
138
|
+
usage = (options[:usage] || self.usage(param))
|
139
|
+
|
140
|
+
args = []
|
141
|
+
|
142
|
+
args << short_flag if short_flag
|
143
|
+
args << if usage
|
144
|
+
"#{long_flag} [#{usage}]"
|
145
|
+
else
|
146
|
+
long_flag
|
147
|
+
end
|
148
|
+
|
149
|
+
args << accepts(param)
|
150
|
+
|
151
|
+
args << "#{param.description}." if param.description
|
152
|
+
args << "Default: #{param.value.inspect}" if param.value
|
153
|
+
|
154
|
+
if param.type <= Types::Hash
|
155
|
+
opts.on(*args) do |value|
|
156
|
+
if param.value.nil?
|
157
|
+
param.value = value
|
158
|
+
else
|
159
|
+
param.value.merge!(param.coerce(value))
|
160
|
+
end
|
161
|
+
end
|
162
|
+
elsif param.type <= Types::Array
|
163
|
+
opts.on(*args) do |value|
|
164
|
+
if param.value.nil?
|
165
|
+
param.value = value
|
166
|
+
else
|
167
|
+
param.value += param.coerce(value)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
else
|
171
|
+
opts.on(*args) do |value|
|
172
|
+
param.value = value
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
#
|
178
|
+
# Defines an OptionParser for a set of parameters.
|
179
|
+
#
|
180
|
+
# @param [Parameter] object
|
181
|
+
# The Class or Object which included Parameters.
|
182
|
+
#
|
183
|
+
# @param [OptionParser] opts
|
184
|
+
# The option parser to define the parameter options within.
|
185
|
+
#
|
186
|
+
# @yield [opts]
|
187
|
+
# If a block is given, it will be passed the newly created OptionParser.
|
188
|
+
#
|
189
|
+
# @yieldparam [OptionParser] opts
|
190
|
+
# The newly created OptionParser.
|
191
|
+
#
|
192
|
+
# @return [OptionParser]
|
193
|
+
# The defined OptionParser.
|
194
|
+
#
|
195
|
+
# @api public
|
196
|
+
#
|
197
|
+
def self.parser(object)
|
198
|
+
OptionParser.new do |opts|
|
199
|
+
object.each_param do |param|
|
200
|
+
define(opts,param)
|
201
|
+
end
|
202
|
+
|
203
|
+
yield opts if block_given?
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
protected
|
208
|
+
|
209
|
+
# accept pattern for Symbols
|
210
|
+
OptionParser.accept(Symbol, /[A-Za-z][A-Za-z0-9_-]*/) do |s,|
|
211
|
+
s.to_sym if s
|
212
|
+
end
|
213
|
+
|
214
|
+
# accept pattern for Hashes
|
215
|
+
OptionParser.accept(Hash, /[^\s:]*:[^\s:]*(\s+[^\s:]*:[^\s:])*/) do |s,|
|
216
|
+
if s
|
217
|
+
Hash[s.split.map { |key_value| key_value.split(':',2) }]
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
222
|
+
end
|
data/lib/parameters/param.rb
CHANGED
@@ -24,6 +24,8 @@ module Parameters
|
|
24
24
|
# @param [String, nil] description
|
25
25
|
# The description of the parameter.
|
26
26
|
#
|
27
|
+
# @api semipublic
|
28
|
+
#
|
27
29
|
def initialize(name,type=nil,description=nil)
|
28
30
|
@name = name.to_sym
|
29
31
|
@type = if (type.kind_of?(Types::Type)) ||
|
@@ -36,8 +38,6 @@ module Parameters
|
|
36
38
|
@description = description
|
37
39
|
end
|
38
40
|
|
39
|
-
protected
|
40
|
-
|
41
41
|
#
|
42
42
|
# Coerces the value into the param type.
|
43
43
|
#
|
@@ -47,6 +47,8 @@ module Parameters
|
|
47
47
|
# @return [Object]
|
48
48
|
# The coerced value.
|
49
49
|
#
|
50
|
+
# @api semipublic
|
51
|
+
#
|
50
52
|
def coerce(value)
|
51
53
|
if (value.nil? || (@type === value))
|
52
54
|
value
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'parameters/exceptions'
|
2
2
|
require 'parameters/class_methods'
|
3
|
+
require 'parameters/module_methods'
|
3
4
|
require 'parameters/class_param'
|
4
5
|
require 'parameters/instance_param'
|
5
6
|
require 'parameters/exceptions'
|
@@ -8,6 +9,11 @@ require 'parameters/extensions/meta'
|
|
8
9
|
module Parameters
|
9
10
|
def self.included(base)
|
10
11
|
base.extend ClassMethods
|
12
|
+
|
13
|
+
if base.kind_of?(Module)
|
14
|
+
# add Module specific methods
|
15
|
+
base.extend Parameters::ModuleMethods
|
16
|
+
end
|
11
17
|
end
|
12
18
|
|
13
19
|
#
|
@@ -17,9 +23,13 @@ module Parameters
|
|
17
23
|
# @param [Hash] values
|
18
24
|
# The names and values to initialize the instance parameters to.
|
19
25
|
#
|
26
|
+
# @api public
|
27
|
+
#
|
20
28
|
def initialize_params(values={})
|
21
|
-
self.class.
|
22
|
-
self.
|
29
|
+
if self.class.included_modules.include?(Parameters)
|
30
|
+
self.class.each_param do |param|
|
31
|
+
self.params[param.name] = param.to_instance(self)
|
32
|
+
end
|
23
33
|
end
|
24
34
|
|
25
35
|
self.params = values if values.kind_of?(Hash)
|
@@ -30,6 +40,8 @@ module Parameters
|
|
30
40
|
# is passed in as the first argument, it will be used to set the values
|
31
41
|
# of parameters described within the `Hash`.
|
32
42
|
#
|
43
|
+
# @api public
|
44
|
+
#
|
33
45
|
def initialize(*args,&block)
|
34
46
|
initialize_params(args.first)
|
35
47
|
end
|
@@ -61,6 +73,8 @@ module Parameters
|
|
61
73
|
# @example
|
62
74
|
# obj.parameter('var',:default => 3, :description => 'my variable')
|
63
75
|
#
|
76
|
+
# @api public
|
77
|
+
#
|
64
78
|
def parameter(name,options={})
|
65
79
|
name = name.to_sym
|
66
80
|
|
@@ -74,6 +88,10 @@ module Parameters
|
|
74
88
|
def #{name}=(new_value)
|
75
89
|
get_param(#{name.inspect}).value = new_value
|
76
90
|
end
|
91
|
+
|
92
|
+
def #{name}?
|
93
|
+
!!get_param(#{name.inspect}).value
|
94
|
+
end
|
77
95
|
}
|
78
96
|
|
79
97
|
# create the new parameter
|
@@ -94,6 +112,8 @@ module Parameters
|
|
94
112
|
# @return [Hash]
|
95
113
|
# The parameteres of the class and it's ancestors.
|
96
114
|
#
|
115
|
+
# @api semipublic
|
116
|
+
#
|
97
117
|
def class_params
|
98
118
|
self.class.params
|
99
119
|
end
|
@@ -102,8 +122,10 @@ module Parameters
|
|
102
122
|
# @return [Hash]
|
103
123
|
# The instance parameters of the object.
|
104
124
|
#
|
125
|
+
# @api semipublic
|
126
|
+
#
|
105
127
|
def params
|
106
|
-
@
|
128
|
+
@parameters ||= {}
|
107
129
|
end
|
108
130
|
|
109
131
|
#
|
@@ -116,6 +138,8 @@ module Parameters
|
|
116
138
|
# obj.params = {:x => 5, :y => 2}
|
117
139
|
# # => {:x=>5, :y=>2}
|
118
140
|
#
|
141
|
+
# @api semipublic
|
142
|
+
#
|
119
143
|
def params=(values)
|
120
144
|
values.each do |name,value|
|
121
145
|
name = name.to_sym
|
@@ -138,6 +162,8 @@ module Parameters
|
|
138
162
|
# @yield [param]
|
139
163
|
# The block that will be passed each instance parameter.
|
140
164
|
#
|
165
|
+
# @api semipublic
|
166
|
+
#
|
141
167
|
def each_param(&block)
|
142
168
|
self.params.each_value(&block)
|
143
169
|
end
|
@@ -150,6 +176,8 @@ module Parameters
|
|
150
176
|
# @example
|
151
177
|
# obj.has_param?('rhost') # => true
|
152
178
|
#
|
179
|
+
# @api semipublic
|
180
|
+
#
|
153
181
|
def has_param?(name)
|
154
182
|
self.params.has_key?(name.to_sym)
|
155
183
|
end
|
@@ -169,6 +197,8 @@ module Parameters
|
|
169
197
|
# @example
|
170
198
|
# obj.get_param('var') # => InstanceParam
|
171
199
|
#
|
200
|
+
# @api semipublic
|
201
|
+
#
|
172
202
|
def get_param(name)
|
173
203
|
name = name.to_sym
|
174
204
|
|
@@ -200,6 +230,8 @@ module Parameters
|
|
200
230
|
#
|
201
231
|
# @since 0.3.0
|
202
232
|
#
|
233
|
+
# @api semipublic
|
234
|
+
#
|
203
235
|
def set_param(name,value)
|
204
236
|
name = name.to_sym
|
205
237
|
|
@@ -225,6 +257,8 @@ module Parameters
|
|
225
257
|
# @example
|
226
258
|
# obj.describe_param('rhost') # => "remote host"
|
227
259
|
#
|
260
|
+
# @api semipublic
|
261
|
+
#
|
228
262
|
def describe_param(name)
|
229
263
|
get_param(name).description
|
230
264
|
end
|
@@ -244,6 +278,8 @@ module Parameters
|
|
244
278
|
# @example
|
245
279
|
# obj.param_value('rhost') # => 80
|
246
280
|
#
|
281
|
+
# @api semipublic
|
282
|
+
#
|
247
283
|
def param_value(name)
|
248
284
|
get_param(name).value
|
249
285
|
end
|
@@ -260,6 +296,8 @@ module Parameters
|
|
260
296
|
# @raise [MissingParam]
|
261
297
|
# One of the instance parameters was not set.
|
262
298
|
#
|
299
|
+
# @api public
|
300
|
+
#
|
263
301
|
def require_params(*names)
|
264
302
|
names.each do |name|
|
265
303
|
name = name.to_s
|
@@ -17,6 +17,18 @@ module Parameters
|
|
17
17
|
@element_type = element_type
|
18
18
|
end
|
19
19
|
|
20
|
+
#
|
21
|
+
# The element type of the Array type.
|
22
|
+
#
|
23
|
+
# @return [Object]
|
24
|
+
# The default element type.
|
25
|
+
#
|
26
|
+
# @since 0.4.0
|
27
|
+
#
|
28
|
+
def self.element_type
|
29
|
+
Object
|
30
|
+
end
|
31
|
+
|
20
32
|
#
|
21
33
|
# Coerces a value into an Array.
|
22
34
|
#
|
@@ -46,6 +58,22 @@ module Parameters
|
|
46
58
|
self.class.to_ruby[@element_type.to_ruby]
|
47
59
|
end
|
48
60
|
|
61
|
+
#
|
62
|
+
# Compares the instance type with another type.
|
63
|
+
#
|
64
|
+
# @param [Array, Type] other
|
65
|
+
# The other type to compare against.
|
66
|
+
#
|
67
|
+
# @return [::Boolean]
|
68
|
+
# Specificies whether the instance type has the same element type
|
69
|
+
# as the other Array instance type.
|
70
|
+
#
|
71
|
+
# @since 0.4.0
|
72
|
+
#
|
73
|
+
def ==(other)
|
74
|
+
super(other) && (@element_type == other.element_type)
|
75
|
+
end
|
76
|
+
|
49
77
|
#
|
50
78
|
# Determines if the value is an Array.
|
51
79
|
#
|
@@ -15,11 +15,35 @@ module Parameters
|
|
15
15
|
#
|
16
16
|
# @param [Type] value_type
|
17
17
|
#
|
18
|
-
def initialize(key_type,value_type)
|
18
|
+
def initialize(key_type=Object,value_type=Object)
|
19
19
|
@key_type = key_type
|
20
20
|
@value_type = value_type
|
21
21
|
end
|
22
22
|
|
23
|
+
#
|
24
|
+
# The key type of the Hash type.
|
25
|
+
#
|
26
|
+
# @return [Object]
|
27
|
+
# The default key type.
|
28
|
+
#
|
29
|
+
# @since 0.4.0
|
30
|
+
#
|
31
|
+
def self.key_type
|
32
|
+
Object
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# The value type of the Hash type.
|
37
|
+
#
|
38
|
+
# @return [Object]
|
39
|
+
# The default value type.
|
40
|
+
#
|
41
|
+
# @since 0.4.0
|
42
|
+
#
|
43
|
+
def self.value_type
|
44
|
+
Object
|
45
|
+
end
|
46
|
+
|
23
47
|
#
|
24
48
|
# Coerces a value into a Hash.
|
25
49
|
#
|
@@ -54,6 +78,25 @@ module Parameters
|
|
54
78
|
::Hash[@key_type.to_ruby => @value_type.to_ruby]
|
55
79
|
end
|
56
80
|
|
81
|
+
#
|
82
|
+
# Compares the instance type with another type.
|
83
|
+
#
|
84
|
+
# @param [Hash, Type] other
|
85
|
+
# The other type to compare against.
|
86
|
+
#
|
87
|
+
# @return [::Boolean]
|
88
|
+
# Specificies whether the instance type has the same key/value
|
89
|
+
# types as the other Hash instance type.
|
90
|
+
#
|
91
|
+
# @since 0.4.0
|
92
|
+
#
|
93
|
+
def ==(other)
|
94
|
+
super(other) && (
|
95
|
+
(@key_type == other.key_type) &&
|
96
|
+
(@value_type == other.value_type)
|
97
|
+
)
|
98
|
+
end
|
99
|
+
|
57
100
|
#
|
58
101
|
# Determines if the Hash, and all keys/values, are related to the Type.
|
59
102
|
#
|
@@ -46,6 +46,58 @@ module Parameters
|
|
46
46
|
def self.coerce(value)
|
47
47
|
end
|
48
48
|
|
49
|
+
#
|
50
|
+
# Compares the instance type to another instance type.
|
51
|
+
#
|
52
|
+
# @param [Type] other
|
53
|
+
# The other instance type.
|
54
|
+
#
|
55
|
+
# @return [::Boolean]
|
56
|
+
# Specifies that the type has the same class as the other instance
|
57
|
+
# type.
|
58
|
+
#
|
59
|
+
# @since 0.4.0
|
60
|
+
#
|
61
|
+
def ==(other)
|
62
|
+
self.class == other.class
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# Determines if the instance of the type is related to another Type.
|
67
|
+
#
|
68
|
+
# @param [Type] type
|
69
|
+
# The other type class.
|
70
|
+
#
|
71
|
+
# @return [::Boolean]
|
72
|
+
# Specifies whether the instance of the type inherites from another
|
73
|
+
# type.
|
74
|
+
#
|
75
|
+
# @since 0.4.0
|
76
|
+
#
|
77
|
+
def <(other)
|
78
|
+
if other.kind_of?(Type)
|
79
|
+
self.class <= other.class
|
80
|
+
else
|
81
|
+
self.class <= other
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
#
|
86
|
+
# Compares the type to another instance or class type.
|
87
|
+
#
|
88
|
+
# @param [Type] type
|
89
|
+
# The other instance or class type.
|
90
|
+
#
|
91
|
+
# @return [::Boolean]
|
92
|
+
# Specifies whether the instance type inherits from the other
|
93
|
+
# class type, or shares the same class as the other instance type.
|
94
|
+
#
|
95
|
+
# @since 0.4.0
|
96
|
+
#
|
97
|
+
def <=(other)
|
98
|
+
(self < other) || (self == other)
|
99
|
+
end
|
100
|
+
|
49
101
|
#
|
50
102
|
# @see ===
|
51
103
|
#
|
data/lib/parameters/version.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'parameters'
|
2
|
+
|
3
|
+
class OptionParameters
|
4
|
+
|
5
|
+
include Parameters
|
6
|
+
|
7
|
+
parameter :path, :description => 'Path to the file'
|
8
|
+
|
9
|
+
parameter :with_foo, :description => 'Multiword param name'
|
10
|
+
|
11
|
+
parameter :type, :type => Symbol,
|
12
|
+
:description => 'Type to use'
|
13
|
+
|
14
|
+
parameter :count, :type => Integer,
|
15
|
+
:default => 100,
|
16
|
+
:description => 'Max count'
|
17
|
+
|
18
|
+
parameter :names, :type => Array[String],
|
19
|
+
:description => 'Names to search for'
|
20
|
+
|
21
|
+
parameter :ids, :type => Set[Integer],
|
22
|
+
:description => 'IDs to search for'
|
23
|
+
|
24
|
+
parameter :verbose, :type => true,
|
25
|
+
:description => 'Enable version'
|
26
|
+
|
27
|
+
parameter :mapping, :type => Hash[Symbol => Integer],
|
28
|
+
:description => 'Mapping of names to integers'
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'classes/option_parameters'
|
3
|
+
require 'parameters/options'
|
4
|
+
|
5
|
+
describe Parameters::Options do
|
6
|
+
let(:object) { OptionParameters.new }
|
7
|
+
let(:params) { object.params }
|
8
|
+
|
9
|
+
describe "flag" do
|
10
|
+
it "should prefix the name with '--'" do
|
11
|
+
subject.flag(params[:path]).should == '--path'
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should replace '_' characters with '-'" do
|
15
|
+
subject.flag(params[:with_foo]).should == '--with-foo'
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should include '[no-]' for Boolean params" do
|
19
|
+
subject.flag(params[:verbose]).should == '--[no-]verbose'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "usage" do
|
24
|
+
it "should use the param name for params without a type" do
|
25
|
+
subject.usage(params[:path]).should == 'PATH'
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should use the param type to derive the USAGE String" do
|
29
|
+
subject.usage(params[:count]).should == 'NUM'
|
30
|
+
end
|
31
|
+
|
32
|
+
context "complex types" do
|
33
|
+
it "should recognize Array params" do
|
34
|
+
subject.usage(params[:names]).should == 'NAMES [...]'
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should recognize Set params" do
|
38
|
+
subject.usage(params[:ids]).should == 'NUM [...]'
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should recognize Hash params" do
|
42
|
+
subject.usage(params[:mapping]).should == 'NAME:NUM [...]'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "accepts" do
|
48
|
+
it "should map Object params to Object" do
|
49
|
+
subject.accepts(params[:path]).should == Object
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should map Boolean params to TrueClass" do
|
53
|
+
subject.accepts(params[:verbose]).should == TrueClass
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should map Array params to Array" do
|
57
|
+
subject.accepts(params[:names]).should == Array
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should map Set params to Array" do
|
61
|
+
subject.accepts(params[:ids]).should == Array
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should map Hash params to Hash" do
|
65
|
+
subject.accepts(params[:mapping]).should == Hash
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "parser" do
|
70
|
+
subject { Parameters::Options.parser(object) }
|
71
|
+
|
72
|
+
it "should set the param values" do
|
73
|
+
path = 'foo.rb'
|
74
|
+
|
75
|
+
subject.parse(['--path', path])
|
76
|
+
|
77
|
+
object.path.should == path
|
78
|
+
end
|
79
|
+
|
80
|
+
context "Symbol params" do
|
81
|
+
it "should accept identifier values" do
|
82
|
+
type = :foo
|
83
|
+
|
84
|
+
subject.parse(['--type', type.to_s])
|
85
|
+
|
86
|
+
object.type.should == type
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should reject non-identifier values" do
|
90
|
+
lambda {
|
91
|
+
subject.parse(['--type', '10'])
|
92
|
+
}.should raise_error(OptionParser::InvalidArgument)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "Array params" do
|
97
|
+
it "should merge multiple values together" do
|
98
|
+
name1 = 'foo'
|
99
|
+
name2 = 'bar'
|
100
|
+
|
101
|
+
subject.parse(['--names', name1, '--names', name2])
|
102
|
+
|
103
|
+
object.names.should == [name1, name2]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context "Set params" do
|
108
|
+
it "should merge multiple values together" do
|
109
|
+
id1 = 10
|
110
|
+
id2 = 20
|
111
|
+
|
112
|
+
subject.parse(['--ids', id1.to_s, '--ids', id2.to_s])
|
113
|
+
|
114
|
+
object.ids.should == Set[id1, id2]
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context "Hash params" do
|
119
|
+
it "should accept 'key:value' pairs" do
|
120
|
+
hash = {:foo => 1}
|
121
|
+
|
122
|
+
subject.parse(['--mapping', 'foo:1'])
|
123
|
+
|
124
|
+
object.mapping.should == hash
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should reject non 'key:value' pairs" do
|
128
|
+
lambda {
|
129
|
+
subject.parse(['--mapping', 'foo'])
|
130
|
+
}.should raise_error(OptionParser::InvalidArgument)
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should merge multiple values together" do
|
134
|
+
hash = {:foo => 1, :bar => 2}
|
135
|
+
|
136
|
+
subject.parse(['--mapping', 'foo:1', '--mapping', 'bar:2'])
|
137
|
+
|
138
|
+
object.mapping.should == hash
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
data/spec/parameters_spec.rb
CHANGED
@@ -36,11 +36,19 @@ describe Parameters do
|
|
36
36
|
subject.param_value(:var_with_default).should == 'thing'
|
37
37
|
end
|
38
38
|
|
39
|
-
it "should provide class methods for paremters" do
|
39
|
+
it "should provide class reader/writter methods for paremters" do
|
40
40
|
subject.var = 1
|
41
41
|
subject.var.should == 1
|
42
42
|
end
|
43
43
|
|
44
|
+
it "should provide class ? method to check if the parameter is set" do
|
45
|
+
subject.var = nil
|
46
|
+
subject.var?.should == false
|
47
|
+
|
48
|
+
subject.var = 2
|
49
|
+
subject.var?.should == true
|
50
|
+
end
|
51
|
+
|
44
52
|
it "should inherite the super-classes parameters" do
|
45
53
|
inherited_class.has_param?(:var).should == true
|
46
54
|
inherited_class.has_param?(:child_var).should == true
|
@@ -111,11 +119,19 @@ describe Parameters do
|
|
111
119
|
subject.param_value(:var_with_default).should == 'thing'
|
112
120
|
end
|
113
121
|
|
114
|
-
it "should provide instance methods for parameters" do
|
122
|
+
it "should provide instance reader/writter methods for parameters" do
|
115
123
|
subject.var = 2
|
116
124
|
subject.var.should == 2
|
117
125
|
end
|
118
126
|
|
127
|
+
it "should provide instance ? methods to check if the parameter was set" do
|
128
|
+
subject.var = nil
|
129
|
+
subject.var?.should == false
|
130
|
+
|
131
|
+
subject.var = 2
|
132
|
+
subject.var?.should == true
|
133
|
+
end
|
134
|
+
|
119
135
|
it "should set instance variables for paramters" do
|
120
136
|
subject.instance_variable_get(:@var_with_default).should == 'thing'
|
121
137
|
|
@@ -226,6 +242,14 @@ describe Parameters do
|
|
226
242
|
subject.new_param.should == 10
|
227
243
|
end
|
228
244
|
|
245
|
+
it "should define ? method to determine if the parameter is set" do
|
246
|
+
subject.new_param = nil
|
247
|
+
subject.new_param?.should == false
|
248
|
+
|
249
|
+
subject.new_param = 10
|
250
|
+
subject.new_param?.should == true
|
251
|
+
end
|
252
|
+
|
229
253
|
it "should set the instance variables of parameters" do
|
230
254
|
subject.instance_variable_get(:@new_param_with_default).should == 5
|
231
255
|
|
data/spec/types/array_spec.rb
CHANGED
@@ -14,14 +14,23 @@ describe Parameters::Types::Array do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
context "instance" do
|
17
|
-
let(:
|
17
|
+
let(:element_type) { Parameters::Types::Integer }
|
18
|
+
let(:numbers) { %w[1 2 3] }
|
18
19
|
|
19
|
-
subject { described_class.new(
|
20
|
+
subject { described_class.new(element_type) }
|
20
21
|
|
21
22
|
it "should have a Ruby type" do
|
22
23
|
subject.to_ruby.should == Array[Integer]
|
23
24
|
end
|
24
25
|
|
26
|
+
it "should be equal to another Array type with the same element-type" do
|
27
|
+
subject.should == described_class.new(element_type)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should be related to the Array type" do
|
31
|
+
subject.should < described_class
|
32
|
+
end
|
33
|
+
|
25
34
|
describe "#===" do
|
26
35
|
it "should check the type of each element" do
|
27
36
|
subject.should_not === numbers
|
data/spec/types/hash_spec.rb
CHANGED
@@ -20,10 +20,20 @@ describe Parameters::Types::Hash do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
context "instance" do
|
23
|
+
it "should be related to the Array type" do
|
24
|
+
subject.should < described_class
|
25
|
+
end
|
26
|
+
|
23
27
|
context "with key-type" do
|
24
|
-
let(:
|
28
|
+
let(:key_type) { Parameters::Types::Symbol }
|
29
|
+
let(:value_type) { Parameters::Types::Object }
|
30
|
+
let(:string_keys) { {'a' => 1, 'b' => 2} }
|
31
|
+
|
32
|
+
subject { described_class.new(key_type,value_type) }
|
25
33
|
|
26
|
-
|
34
|
+
it "should be equal to another Hash type with the same key/value types" do
|
35
|
+
subject.should == described_class.new(key_type,value_type)
|
36
|
+
end
|
27
37
|
|
28
38
|
it "should have a Ruby type" do
|
29
39
|
subject.to_ruby.should == Hash[Symbol => Object]
|
@@ -45,9 +55,15 @@ describe Parameters::Types::Hash do
|
|
45
55
|
end
|
46
56
|
|
47
57
|
context "with value-type" do
|
48
|
-
let(:
|
58
|
+
let(:key_type) { Parameters::Types::Object }
|
59
|
+
let(:value_type) { Parameters::Types::Integer }
|
60
|
+
let(:string_values) { {:a => '1', :b => '2'} }
|
61
|
+
|
62
|
+
subject { described_class.new(key_type,value_type) }
|
49
63
|
|
50
|
-
|
64
|
+
it "should be equal to another Hash type with the same key/value types" do
|
65
|
+
subject.should == described_class.new(key_type,value_type)
|
66
|
+
end
|
51
67
|
|
52
68
|
it "should have a Ruby type" do
|
53
69
|
subject.to_ruby.should == Hash[Object => Integer]
|
data/spec/types/set_spec.rb
CHANGED
@@ -15,14 +15,23 @@ describe Parameters::Types::Set do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
context "instance" do
|
18
|
-
let(:
|
18
|
+
let(:element_type) { Parameters::Types::Integer }
|
19
|
+
let(:numbers) { %w[1 2 3] }
|
19
20
|
|
20
|
-
subject { described_class.new(
|
21
|
+
subject { described_class.new(element_type) }
|
21
22
|
|
22
23
|
it "should have a Ruby type" do
|
23
24
|
subject.to_ruby.should == Set[Integer]
|
24
25
|
end
|
25
26
|
|
27
|
+
it "should be equal to another Set type with the same element-type" do
|
28
|
+
subject.should == described_class.new(element_type)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should be related to the Array type" do
|
32
|
+
subject.should < described_class
|
33
|
+
end
|
34
|
+
|
26
35
|
describe "#===" do
|
27
36
|
it "should check the type of each element" do
|
28
37
|
subject.should_not === numbers
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parameters
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-12-
|
12
|
+
date: 2011-12-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ore-tasks
|
16
|
-
requirement: &
|
16
|
+
requirement: &23003040 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0.4'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *23003040
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &23002520 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '2.4'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *23002520
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: yard
|
38
|
-
requirement: &
|
38
|
+
requirement: &23002020 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: '0.7'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *23002020
|
47
47
|
description: Parameters allows you to add annotated variables to your classes which
|
48
48
|
may have configurable default values.
|
49
49
|
email: postmodern.mod3@gmail.com
|
@@ -73,6 +73,8 @@ files:
|
|
73
73
|
- lib/parameters/extensions/meta.rb
|
74
74
|
- lib/parameters/extensions/meta/object.rb
|
75
75
|
- lib/parameters/instance_param.rb
|
76
|
+
- lib/parameters/module_methods.rb
|
77
|
+
- lib/parameters/options.rb
|
76
78
|
- lib/parameters/param.rb
|
77
79
|
- lib/parameters/parameters.rb
|
78
80
|
- lib/parameters/types.rb
|
@@ -101,9 +103,11 @@ files:
|
|
101
103
|
- spec/classes/custom_type.rb
|
102
104
|
- spec/classes/inherited_parameters.rb
|
103
105
|
- spec/classes/module_parameters.rb
|
106
|
+
- spec/classes/option_parameters.rb
|
104
107
|
- spec/classes/other_parameters.rb
|
105
108
|
- spec/classes/test_parameters.rb
|
106
109
|
- spec/instance_param_spec.rb
|
110
|
+
- spec/options_spec.rb
|
107
111
|
- spec/parameters_spec.rb
|
108
112
|
- spec/spec_helper.rb
|
109
113
|
- spec/types/array_spec.rb
|
@@ -151,6 +155,7 @@ summary: Allows you to add annotated variables to your classes
|
|
151
155
|
test_files:
|
152
156
|
- spec/class_param_spec.rb
|
153
157
|
- spec/instance_param_spec.rb
|
158
|
+
- spec/options_spec.rb
|
154
159
|
- spec/parameters_spec.rb
|
155
160
|
- spec/types/array_spec.rb
|
156
161
|
- spec/types/boolean_spec.rb
|