parameters 0.1.9 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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