parameters 0.1.9 → 0.2.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.
@@ -0,0 +1,9 @@
1
+ doc
2
+ pkg
3
+ tmp/*
4
+ .DS_Store
5
+ .yardoc
6
+ *.db
7
+ *.log
8
+ *.swp
9
+ *~
@@ -0,0 +1 @@
1
+ --colour --format specdoc
@@ -0,0 +1 @@
1
+ --markup markdown --title 'Parameters Documentation' --protected --files ChangeLog.md,LICENSE.txt
@@ -0,0 +1,98 @@
1
+ ### 0.2.0 / 2010-02-18
2
+
3
+ * Migrated to [Jeweler](http://github.com/technicalpickles/jeweler)
4
+ for packaging rubygems.
5
+ * Added type enforcement / coercion to parameters:
6
+ * Added the `:type` option to the `parameter` method.
7
+ * Available types:
8
+ * Array[Class]
9
+ * Array
10
+ * Set[Class]
11
+ * Set
12
+ * URI
13
+ * Regexp
14
+ * DateTime
15
+ * Date
16
+ * Symbol
17
+ * String
18
+ * Integer
19
+ * Float
20
+ * true (for boolean types).
21
+ * Removed `Parameters::Parser` in favor of type enforcement / coercion.
22
+ * Switched to MarkDown formatted YARD documentation.
23
+ * Moved the YARD parameter handlers into
24
+ [yard-parameters](http://github.com/postmodern/yard-parameters) library.
25
+
26
+ ### 0.1.9 / 2009-01-30
27
+
28
+ * Require RSpec >= 1.3.0.
29
+ * Require YARD >= 0.5.3.
30
+ * Added {Parameters::ClassMethods}.
31
+
32
+ ### 0.1.8 / 2009-09-21
33
+
34
+ * Require Hoe >= 2.3.3.
35
+ * Require YARD >= 0.2.3.5.
36
+ * Require RSpec >= 1.2.8.
37
+ * Use 'hoe/signing' for signed RubyGems.
38
+ * Moved to YARD based documentation.
39
+ * Added YARD handlers for documenting parameter method calls.
40
+ * All specs pass on JRuby 1.3.1.
41
+
42
+ ### 0.1.7 / 2009-07-19
43
+
44
+ * Renamed Parameters#initialize_parameters to
45
+ {Parameters#initialize_params}.
46
+ * Adjust spacing in the output of {Parameters::ClassParam#to_s}
47
+ and {Parameters::InstanceParam#to_s}.
48
+ * Specifically check if the instance variable is nil
49
+ before initializing it to the default value of the parameter.
50
+ * Handle default value callbacks in {Parameters#parameter}.
51
+ * Check the arity of all default value callbacks, before
52
+ passing self to them.
53
+ * {Parameters#require_params} now specifically tests if
54
+ the instance variable of the parameter is nil.
55
+ * Added more specs.
56
+
57
+ ### 0.1.6 / 2009-05-11
58
+
59
+ * Fixed a bug in {Parameters::ClassMethods#params=} and {Parameters#params=},
60
+ where they were not handling {Parameters::ClassParam} or
61
+ {Parameters::InstanceParam} objects properly.
62
+ * Added more specs.
63
+
64
+ ### 0.1.5 / 2009-05-06
65
+
66
+ * Added Parameters::Parser for parsing parameter values passed in from
67
+ the command-line or the web.
68
+ * Changed {Parameters::MissingParam} and {Parameters::ParamNotFound} to
69
+ inherit from StandardError.
70
+ * All specs pass on Ruby 1.9.1-p0.
71
+
72
+ ### 0.1.4 / 2009-01-17
73
+
74
+ * All specs now pass with RSpec 1.1.12.
75
+ * All specs pass on Ruby 1.9.1-rc1.
76
+
77
+ ### 0.1.3 / 2009-01-14
78
+
79
+ * Allow the use of lambdas to generate the default values of parameters.
80
+ * Fixed typos in the README.txt.
81
+
82
+ ### 0.1.2 / 2009-01-06
83
+
84
+ * When printing parameter values, print the inspected version of the value.
85
+
86
+ ### 0.1.1 / 2008-12-27
87
+
88
+ * Added the require_params helper method.
89
+ * Added print_params methods for displaying parameters of a class or an
90
+ object.
91
+
92
+ ### 0.1.0 / 2008-12-03
93
+
94
+ * Initial release.
95
+ * Added {Parameters::ClassMethods#params=} and {Parameters#params=} methods.
96
+ * Allow Parameters#initialize to accept a Hash of parameter values.
97
+ * Added more specs.
98
+
@@ -0,0 +1,22 @@
1
+
2
+ Copyright (c) 2008-2010 Hal Brodigan
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ 'Software'), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
@@ -0,0 +1,90 @@
1
+ # Parameters
2
+
3
+ * [parameters.rubyforge.org](http://parameters.rubyforge.org/)
4
+ * [github.com/postmodern/parameters](http://github.com/postmodern/parameters/)
5
+ * Postmodern (postmodern.mod3 at gmail.com)
6
+
7
+ ## Description
8
+
9
+ Parameters allows you to add annotated variables to your classes which may
10
+ have configurable default values.
11
+
12
+ ## Features
13
+
14
+ * Give parameters default values.
15
+ * Default values maybe either objects or lambdas used to generate the
16
+ default value.
17
+ * Change default values of parameters.
18
+ * Enforce types on the values of parameters.
19
+ * Give descriptions to parameters.
20
+ * Set parameters en-mass.
21
+
22
+ ## Examples
23
+
24
+ class Octagon
25
+
26
+ include Parameters
27
+
28
+ #
29
+ # A parameter with a default value
30
+ #
31
+ parameter :x, :default => 0
32
+
33
+ #
34
+ # Another parameter with a default value
35
+ #
36
+ parameter :y, :default => 0.5
37
+
38
+ #
39
+ # A parameter with an enforced type and description.
40
+ #
41
+ # Availble types are: Array[Class], Array, Set[Class], Set,
42
+ # URI, Regexp, DateTime, Date, Symbol, String, Integer, Float
43
+ # and true (for boolean types).
44
+ #
45
+ parameter :radius,
46
+ :type => Float,
47
+ :description => 'The radius of the Octagon'
48
+
49
+ #
50
+ # A parameter with a lambda for a default value
51
+ #
52
+ parameter :opacity,
53
+ :default => lambda { rand },
54
+ :description => 'The opacity of the Octagon'
55
+
56
+ end
57
+
58
+ # Create an object with default values for all parameters
59
+ oct = Octagon.new
60
+ oct.x # => 0
61
+ oct.y # => 0.5
62
+ oct.opacity # => 0.25
63
+
64
+ # Create an object with the given parameter values.
65
+ oct = Octagon.new(:radius => 10)
66
+ oct.radius # => 10
67
+ oct.opacity # => 0.7
68
+
69
+ # Set parameter values of a class
70
+ Octagon.radius = 33
71
+ Octagon.opacity = 0.3
72
+
73
+ # Create an object with parameter defaulte values inherited from the
74
+ # class parameters
75
+ oct = Octagon.new
76
+ oct.radius # => 33
77
+ oct.opacity # => 0.3
78
+
79
+ # Coerce data from the command-line into the given parameter type
80
+ oct.radius = ARGV[2]
81
+ oct.radius # => 89.455
82
+
83
+ ## Install
84
+
85
+ $ sudo gem install parameters
86
+
87
+ ## License
88
+
89
+ See {file:LICENSE.txt} for license information.
90
+
data/Rakefile CHANGED
@@ -1,23 +1,41 @@
1
- # -*- ruby -*-
2
-
3
1
  require 'rubygems'
4
- require 'hoe'
5
- require 'hoe/signing'
2
+ require 'rake'
3
+ require './lib/parameters/version.rb'
6
4
 
7
- Hoe.plugin :yard
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gem|
8
+ gem.name = 'parameters'
9
+ gem.version = Parameters::VERSION
10
+ gem.summary = %Q{Allows you to add annotated variables to your classes}
11
+ gem.description = %Q{Parameters allows you to add annotated variables to your classes which may have configurable default values.}
12
+ gem.email = 'postmodern.mod3@gmail.com'
13
+ gem.homepage = 'http://github.com/postmodern/parameters'
14
+ gem.authors = ['Postmodern']
15
+ gem.add_development_dependency 'rspec', '>= 1.3.0'
16
+ gem.add_development_dependency 'yard', '>= 0.5.3'
17
+ gem.has_rdoc = 'yard'
18
+ end
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
21
+ end
8
22
 
9
- Hoe.spec('parameters') do
10
- self.developer('Postmodern','postmodern.mod3@gmail.com')
23
+ require 'spec/rake/spectask'
24
+ Spec::Rake::SpecTask.new(:spec) do |spec|
25
+ spec.libs += ['lib', 'spec']
26
+ spec.spec_files = FileList['spec/**/*_spec.rb']
27
+ spec.spec_opts = ['--options', '.specopts']
28
+ end
11
29
 
12
- self.rspec_options += ['--colour', '--format', 'specdoc']
30
+ task :spec => :check_dependencies
31
+ task :default => :spec
13
32
 
14
- self.yard_options += ['--protected']
15
- self.remote_yard_dir = '/'
33
+ begin
34
+ require 'yard'
16
35
 
17
- self.extra_dev_deps += [
18
- ['rspec', '>=1.3.0'],
19
- ['yard', '>=0.5.3']
20
- ]
36
+ YARD::Rake::YardocTask.new
37
+ rescue LoadError
38
+ task :yard do
39
+ abort "YARD is not available. In order to run yard, you must: gem install yard"
40
+ end
21
41
  end
22
-
23
- # vim: syntax=Ruby
@@ -43,12 +43,15 @@ module Parameters
43
43
  # @param [Hash] options
44
44
  # Additional options.
45
45
  #
46
- # @option options [String] :description
47
- # The description for the new parameter.
46
+ # @option options [Class, Array[Class]] :type
47
+ # The type to enforce the parameter values to.
48
48
  #
49
49
  # @option options [Object, Proc] :default
50
50
  # The default value for the new parameter.
51
51
  #
52
+ # @option options [String] :description
53
+ # The description for the new parameter.
54
+ #
52
55
  # @example
53
56
  # parameter 'var'
54
57
  #
@@ -59,7 +62,12 @@ module Parameters
59
62
  name = name.to_sym
60
63
 
61
64
  # add the parameter to the class params list
62
- params[name] = Parameters::ClassParam.new(name,options[:description],options[:default])
65
+ params[name] = Parameters::ClassParam.new(
66
+ name,
67
+ options[:type],
68
+ options[:description],
69
+ options[:default]
70
+ )
63
71
 
64
72
  # define the reader class method for the parameter
65
73
  meta_def(name) do
@@ -4,7 +4,7 @@ module Parameters
4
4
  class ClassParam < Param
5
5
 
6
6
  # Default value of the class parameter
7
- attr_accessor :value
7
+ attr_reader :value
8
8
 
9
9
  #
10
10
  # Creates a new ClassParam object.
@@ -12,18 +12,36 @@ module Parameters
12
12
  # @param [Symbol, String] name
13
13
  # The name of the class parameter.
14
14
  #
15
+ # @param [Class, Array[Class]] type
16
+ # The enforced type of the class parameter.
17
+ #
15
18
  # @param [String, nil] description
16
19
  # The description of the class parameter.
17
20
  #
18
21
  # @param [Object, nil] value
19
22
  # The default value of the class parameter.
20
23
  #
21
- def initialize(name,description=nil,value=nil)
22
- super(name,description)
24
+ def initialize(name,type=nil,description=nil,value=nil)
25
+ super(name,type,description)
23
26
 
24
27
  @value = value
25
28
  end
26
29
 
30
+ #
31
+ # Sets the value of the class param.
32
+ #
33
+ # @param [Object] value
34
+ # The new value of the class param.
35
+ #
36
+ # @return [Object]
37
+ # The new value of the class param.
38
+ #
39
+ # @since 0.2.0
40
+ #
41
+ def value=(new_value)
42
+ @value = coerce(new_value)
43
+ end
44
+
27
45
  #
28
46
  # @return [String]
29
47
  # The representation of the class param.
@@ -1,3 +1,5 @@
1
+ require 'parameters/param'
2
+
1
3
  module Parameters
2
4
  class InstanceParam < Param
3
5
 
@@ -14,11 +16,14 @@ module Parameters
14
16
  # @param [Symbol, String] name
15
17
  # The name of the instance parameter.
16
18
  #
19
+ # @param [Class, Array[Class]] type
20
+ # The enforced type of the instance parameter.
21
+ #
17
22
  # @param [String, nil] description
18
23
  # The description of the instance parameter.
19
24
  #
20
- def initialize(object,name,description=nil)
21
- super(name,description)
25
+ def initialize(object,name,type=nil,description=nil)
26
+ super(name,type,description)
22
27
 
23
28
  @object = object
24
29
  end
@@ -28,7 +33,7 @@ module Parameters
28
33
  # The value of the instance param.
29
34
  #
30
35
  def value
31
- @object.instance_variable_get("@#{@name}".to_sym)
36
+ @object.instance_variable_get(:"@#{@name}")
32
37
  end
33
38
 
34
39
  #
@@ -41,7 +46,7 @@ module Parameters
41
46
  # The new value of the instance param.
42
47
  #
43
48
  def value=(value)
44
- @object.instance_variable_set("@#{@name}".to_sym,value)
49
+ @object.instance_variable_set(:"@#{@name}",coerce(value))
45
50
  end
46
51
 
47
52
  #
@@ -1,9 +1,16 @@
1
+ require 'set'
2
+ require 'uri'
3
+ require 'date'
4
+
1
5
  module Parameters
2
6
  class Param
3
7
 
4
8
  # Name of parameter
5
9
  attr_reader :name
6
10
 
11
+ # Enforced type of the parameter
12
+ attr_reader :type
13
+
7
14
  # Description of parameter
8
15
  attr_reader :description
9
16
 
@@ -13,13 +20,321 @@ module Parameters
13
20
  # @param [Symbol, String] name
14
21
  # The name of the parameter.
15
22
  #
23
+ # @param [Class] type
24
+ # The enforced type of the parameter.
25
+ #
16
26
  # @param [String, nil] description
17
27
  # The description of the parameter.
18
28
  #
19
- def initialize(name,description=nil)
29
+ def initialize(name,type=nil,description=nil)
20
30
  @name = name.to_sym
31
+ @type = type
21
32
  @description = description
22
33
  end
23
34
 
35
+ protected
36
+
37
+ # Type classes and their coercion methods
38
+ TYPE_COERSION = {
39
+ Set => :coerce_set,
40
+ Array => :coerce_array,
41
+ URI => :coerce_uri,
42
+ Regexp => :coerce_regexp,
43
+ DateTime => :coerce_date,
44
+ Date => :coerce_date,
45
+ Symbol => :coerce_symbol,
46
+ String => :coerce_string,
47
+ Integer => :coerce_integer,
48
+ Float => :coerce_float,
49
+ true => :coerce_boolean
50
+ }
51
+
52
+ #
53
+ # Coerces a given value into a specific type.
54
+ #
55
+ # @param [Class] type
56
+ # The type to coerce the value into.
57
+ #
58
+ # @param [Object] value
59
+ # The value to coerce.
60
+ #
61
+ # @return [Object]
62
+ # The coerced value.
63
+ #
64
+ # @since 0.2.0
65
+ #
66
+ def coerce_type(type,value)
67
+ if value.nil?
68
+ nil
69
+ elsif type.kind_of?(Set)
70
+ coerce_array(Array,value).map { |element|
71
+ coerce_type(type.first,element)
72
+ }.to_set
73
+ elsif type.kind_of?(Array)
74
+ coerce_array(Array,value).map do |element|
75
+ coerce_type(type.first,element)
76
+ end
77
+ elsif (method_name = TYPE_COERSION[type])
78
+ self.send(method_name,type,value)
79
+ else
80
+ value
81
+ end
82
+ end
83
+
84
+ #
85
+ # Coerces a given value into the `type` of the param.
86
+ #
87
+ # @param [Object] value
88
+ # The value to coerce.
89
+ #
90
+ # @return [Object]
91
+ # The coerced value.
92
+ #
93
+ # @since 0.2.0
94
+ #
95
+ def coerce(value)
96
+ coerce_type(@type,value)
97
+ end
98
+
99
+ #
100
+ # Coerces a given value into a `Set`.
101
+ #
102
+ # @param [Set[Class]] type
103
+ # An optional `Set` containing the type to coerce the elements
104
+ # of the given value to.
105
+ #
106
+ # @param [Enumerable, Object] value
107
+ # The value to coerce into a `Set`.
108
+ #
109
+ # @return [Set]
110
+ # The coerced value.
111
+ #
112
+ # @since 0.2.0
113
+ #
114
+ def coerce_set(type,value)
115
+ if value.kind_of?(Set)
116
+ value
117
+ elsif (value.kind_of?(Enumerable) || value.respond_to?(:to_set))
118
+ value.to_set
119
+ else
120
+ Set[value]
121
+ end
122
+ end
123
+
124
+ #
125
+ # Coerces a given value into an `Array`.
126
+ #
127
+ # @param [Array[Class]] type
128
+ # An optional `Array` containing the type to coerce the elements
129
+ # of the given value to.
130
+ #
131
+ # @param [Enumerable, Object] value
132
+ # The value to coerce into an `Array`.
133
+ #
134
+ # @return [Array]
135
+ # The coerced value.
136
+ #
137
+ # @since 0.2.0
138
+ #
139
+ def coerce_array(type,value)
140
+ if value.kind_of?(Array)
141
+ value
142
+ elsif (value.kind_of?(Enumerable) || value.respond_to?(:to_a))
143
+ value.to_a
144
+ else
145
+ [value]
146
+ end
147
+ end
148
+
149
+ #
150
+ # Coerces a given value into a `URI`.
151
+ #
152
+ # @param [Class] type
153
+ # The `URI` type to coerce to.
154
+ #
155
+ # @param [URI::Generic, #to_s] value
156
+ # The value to coerce into a `URI`.
157
+ #
158
+ # @return [URI::Generic]
159
+ # The coerced value.
160
+ #
161
+ # @since 0.2.0
162
+ #
163
+ def coerce_uri(type,value)
164
+ if value.kind_of?(type)
165
+ value
166
+ else
167
+ URI.parse(value.to_s)
168
+ end
169
+ end
170
+
171
+ #
172
+ # Coerces a given value into a `Regexp`.
173
+ #
174
+ # @param [Class] type
175
+ # The `Regexp` type to coerce to.
176
+ #
177
+ # @param [Regexp, #to_s] value
178
+ # The value to coerce into a `Regexp`.
179
+ #
180
+ # @return [Regexp]
181
+ # The coerced value.
182
+ #
183
+ # @since 0.2.0
184
+ #
185
+ def coerce_regexp(type,value)
186
+ if value.kind_of?(Regexp)
187
+ value
188
+ else
189
+ Regexp.new(value.to_s)
190
+ end
191
+ end
192
+
193
+ #
194
+ # Coerces a given value into a `Symbol`.
195
+ #
196
+ # @param [Class] type
197
+ # The `Symbol` class.
198
+ #
199
+ # @param [#to_s] value
200
+ # The value to coerce.
201
+ #
202
+ # @return [Symbol]
203
+ # The coerced value.
204
+ #
205
+ # @since 0.2.0
206
+ #
207
+ def coerce_symbol(type,value)
208
+ if value.kind_of?(type)
209
+ value
210
+ else
211
+ value.to_s.to_sym
212
+ end
213
+ end
214
+
215
+ #
216
+ # Coerces a given value into a `String`.
217
+ #
218
+ # @param [Class] type
219
+ # The `String` class.
220
+ #
221
+ # @param [#to_s] value
222
+ # The value to coerce into a `String`.
223
+ #
224
+ # @return [String]
225
+ # The coerced value.
226
+ #
227
+ # @since 0.2.0
228
+ #
229
+ def coerce_string(type,value)
230
+ if value.kind_of?(type)
231
+ value
232
+ else
233
+ value.to_s
234
+ end
235
+ end
236
+
237
+ #
238
+ # Coerces a given value into an `Integer`.
239
+ #
240
+ # @param [Class]
241
+ # The Integer class.
242
+ #
243
+ # @param [String, #to_i] value
244
+ # The value to coerce into an `Integer`.
245
+ #
246
+ # @return [Integer]
247
+ # The coerced value.
248
+ #
249
+ # @since 0.2.0
250
+ #
251
+ def coerce_integer(type,value)
252
+ if value.kind_of?(type)
253
+ value
254
+ elsif value.kind_of?(String)
255
+ base = if value[0..1] == '0x'
256
+ 16
257
+ elsif value[0..0] == '0'
258
+ 8
259
+ else
260
+ 10
261
+ end
262
+
263
+ value.to_i(base)
264
+ elsif value.respond_to?(:to_i)
265
+ value.to_i
266
+ else
267
+ 0
268
+ end
269
+ end
270
+
271
+ #
272
+ # Coerces a given value into a `Float`.
273
+ #
274
+ # @param [Class] type
275
+ # The `Float` class.
276
+ #
277
+ # @param [String, #to_f] value
278
+ # The value to coerce into a `Float`.
279
+ #
280
+ # @return [Float]
281
+ # The coerced value.
282
+ #
283
+ # @since 0.2.0
284
+ #
285
+ def coerce_float(type,value)
286
+ if value.kind_of?(type)
287
+ value
288
+ elsif (value.kind_of?(String) || value.respond_to?(:to_f))
289
+ value.to_f
290
+ else
291
+ 0.0
292
+ end
293
+ end
294
+
295
+ #
296
+ # Coerces a given value into a `DateTime` or `Date`.
297
+ #
298
+ # @param [Class] type
299
+ # The `DateTime` or `Date` class.
300
+ #
301
+ # @param [#to_s] value
302
+ # The value to coerce into either a `Date` or `DateTime` object.
303
+ #
304
+ # @return [DateTime, Date]
305
+ # The coerced value.
306
+ #
307
+ # @since 0.2.0
308
+ #
309
+ def coerce_date(type,value)
310
+ if value.kind_of?(type)
311
+ value
312
+ else
313
+ type.parse(value.to_s)
314
+ end
315
+ end
316
+
317
+ #
318
+ # Coerces a given value into either a `true` or `false` value.
319
+ #
320
+ # @param [true] type
321
+ #
322
+ # @param [TrueClass, FalseClass, String, Symbol] value
323
+ # The value to coerce into either a `true` or `false` value.
324
+ #
325
+ # @return [TrueClass, FalseClass]
326
+ # The coerced value.
327
+ #
328
+ # @since 0.2.0
329
+ #
330
+ def coerce_boolean(type,value)
331
+ case value
332
+ when FalseClass, NilClass, 'false', :false
333
+ false
334
+ else
335
+ true
336
+ end
337
+ end
338
+
24
339
  end
25
340
  end