parameters 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ === 0.1.0 / 2008-12-03
2
+
3
+ * Initial release.
4
+ * Added Parameters.params= and Parameters#params= methods.
5
+ * Allow Parameters#initialize to accept a Hash of parameter values.
6
+ * Added more specs.
7
+
@@ -0,0 +1,19 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/parameters.rb
6
+ lib/parameters/exceptions.rb
7
+ lib/parameters/exceptions/missing_param.rb
8
+ lib/parameters/exceptions/param_not_found.rb
9
+ lib/parameters/extensions.rb
10
+ lib/parameters/extensions/meta.rb
11
+ lib/parameters/extensions/meta/object.rb
12
+ lib/parameters/class_param.rb
13
+ lib/parameters/instance_param.rb
14
+ lib/parameters/param.rb
15
+ lib/parameters/parameters.rb
16
+ lib/parameters/version.rb
17
+ tasks/spec.rb
18
+ spec/spec_helper.rb
19
+ spec/parameters_spec.rb
@@ -0,0 +1,70 @@
1
+ = Parameters
2
+
3
+ * http://parameters.rubyforge.org/
4
+ * https://github.com/postmodern/parameters/tree
5
+ * Postmodern (postmodern.mod3 at gmail.com)
6
+
7
+ == DESCRIPTION:
8
+
9
+ Parameters allows you to add annoted variables to your classes which may
10
+ have configurable default values.
11
+
12
+ == FEATURES:
13
+
14
+ * Give parameters default values.
15
+ * Change default values of parameters.
16
+ * Give descriptions to parameters.
17
+
18
+ == EXAMPLES:
19
+
20
+ class Octagon
21
+
22
+ include Parameters
23
+
24
+ parameter :x, :value => 0
25
+
26
+ parameter :y, :value => 0.5
27
+
28
+ parameter :radius, :description => 'The radius of the Octagon'
29
+
30
+ end
31
+
32
+ oct = Octagon.new
33
+ oct.x # => 0
34
+ oct.y # => 0.5
35
+
36
+ oct = Octagon.new(:radius => 10)
37
+ oct.radius # => 10
38
+
39
+ Octagon.radius = 33
40
+ oct = Octagon.new
41
+ oct.radius # => 33
42
+
43
+ == INSTALL:
44
+
45
+ $ sudo gem install parameters
46
+
47
+ == LICENSE:
48
+
49
+ The MIT License
50
+
51
+ Copyright (c) 2008 Hal Brodigan
52
+
53
+ Permission is hereby granted, free of charge, to any person obtaining
54
+ a copy of this software and associated documentation files (the
55
+ 'Software'), to deal in the Software without restriction, including
56
+ without limitation the rights to use, copy, modify, merge, publish,
57
+ distribute, sublicense, and/or sell copies of the Software, and to
58
+ permit persons to whom the Software is furnished to do so, subject to
59
+ the following conditions:
60
+
61
+ The above copyright notice and this permission notice shall be
62
+ included in all copies or substantial portions of the Software.
63
+
64
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
65
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
66
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
67
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
68
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
69
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
70
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,14 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './tasks/spec.rb'
6
+ require './lib/parameters/version.rb'
7
+
8
+ Hoe.new('parameters', Parameters::VERSION) do |p|
9
+ p.rubyforge_name = 'parameters'
10
+ p.developer('Postmodern','postmodern.mod3@gmail.com')
11
+ p.remote_rdoc_dir = '/'
12
+ end
13
+
14
+ # vim: syntax=Ruby
@@ -0,0 +1,4 @@
1
+ require 'parameters/param'
2
+ require 'parameters/class_param'
3
+ require 'parameters/instance_param'
4
+ require 'parameters/parameters'
@@ -0,0 +1,20 @@
1
+ require 'parameters/param'
2
+
3
+ module Parameters
4
+ class ClassParam < Param
5
+
6
+ # Default value of the class parameter
7
+ attr_accessor :value
8
+
9
+ #
10
+ # Creates a new ClassParam object with the specified _name_,
11
+ # given _description_ and _value_.
12
+ #
13
+ def initialize(name,description='',value=nil)
14
+ super(name,description)
15
+
16
+ @value = value
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,2 @@
1
+ require 'parameters/exceptions/param_not_found'
2
+ require 'parameters/exceptions/missing_param'
@@ -0,0 +1,4 @@
1
+ module Parameters
2
+ class MissingParam < RuntimeError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Parameters
2
+ class ParamNotFound < RuntimeError
3
+ end
4
+ end
@@ -0,0 +1 @@
1
+ require 'parameters/extensions/meta'
@@ -0,0 +1 @@
1
+ require 'parameters/extensions/meta/object'
@@ -0,0 +1,24 @@
1
+ # metaprogramming assistant -- metaid.rb
2
+ class Object # :nodoc:
3
+ # The hidden singleton lurks behind everyone
4
+ def metaclass; class << self; self; end; end
5
+ def meta_eval(&blk); metaclass.instance_eval(&blk); end
6
+
7
+ # A class_eval version of meta_eval
8
+ def metaclass_eval(&blk); metaclass.class_eval(&blk); end
9
+
10
+ # A class_def version of meta_def
11
+ def metaclass_def(name, &blk)
12
+ metaclass_eval { define_method(name, &blk) }
13
+ end
14
+
15
+ # Adds methods to a metaclass
16
+ def meta_def(name, &blk)
17
+ meta_eval { define_method(name, &blk) }
18
+ end
19
+
20
+ # Defines an instance method within a class
21
+ def class_def(name, &blk)
22
+ class_eval { define_method(name, &blk) }
23
+ end
24
+ end
@@ -0,0 +1,39 @@
1
+ module Parameters
2
+ class InstanceParam < Param
3
+
4
+ # Owning object
5
+ attr_reader :object
6
+
7
+ #
8
+ # Creates a new InstanceParam object with the specified _object_ and
9
+ # _name_, and the given _description_.
10
+ #
11
+ def initialize(object,name,description='')
12
+ super(name,description)
13
+
14
+ @object = object
15
+ end
16
+
17
+ #
18
+ # Returns the value of the instance param.
19
+ #
20
+ def value
21
+ @object.instance_variable_get("@#{@name}")
22
+ end
23
+
24
+ #
25
+ # Sets the value of the instance param.
26
+ #
27
+ def value=(value)
28
+ @object.instance_variable_set("@#{@name}",value)
29
+ end
30
+
31
+ #
32
+ # Inspects the instance params value.
33
+ #
34
+ def inspect
35
+ value.inspect
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,20 @@
1
+ module Parameters
2
+ class Param
3
+
4
+ # Name of parameter
5
+ attr_reader :name
6
+
7
+ # Description of parameter
8
+ attr_reader :description
9
+
10
+ #
11
+ # Creates a new Param object with the specified _name_ and the given
12
+ # _description_.
13
+ #
14
+ def initialize(name,description='')
15
+ @name = name.to_sym
16
+ @description = description
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,290 @@
1
+ require 'parameters/class_param'
2
+ require 'parameters/instance_param'
3
+ require 'parameters/exceptions'
4
+ require 'parameters/extensions/meta'
5
+
6
+ module Parameters
7
+ def self.included(base) # :nodoc:
8
+ base.metaclass_eval do
9
+ #
10
+ # Returns the +Hash+ of parameters for the class.
11
+ #
12
+ def params
13
+ @params ||= {}
14
+ end
15
+
16
+ #
17
+ # Sets the values of the class parameters described in the
18
+ # _values_ +Hash+.
19
+ #
20
+ # Test.params = {:x => 5, :y => 2}
21
+ # # => {:x=>5, :y=>2}
22
+ #
23
+ def params=(values)
24
+ values.each do |name,value|
25
+ if has_param?(name)
26
+ get_param(name).value = value
27
+ end
28
+ end
29
+ end
30
+
31
+ #
32
+ # Adds a new parameters with the specified _name_ and the given
33
+ # _options_ to the Class.
34
+ #
35
+ # _options_ may contain the following keys:
36
+ # <tt>:description</tt>:: The description of the parameter.
37
+ # <tt>:default</tt>:: The default value the parameter will have.
38
+ #
39
+ # parameter 'var'
40
+ #
41
+ # parameter 'var', :default => 3, :description => 'my variable'
42
+ #
43
+ def parameter(name,options={})
44
+ name = name.to_sym
45
+
46
+ # add the parameter to the class params list
47
+ params[name] = Parameters::ClassParam.new(name,options[:description],options[:default])
48
+
49
+ # define the reader class method for the parameter
50
+ meta_def(name) do
51
+ params[name].value
52
+ end
53
+
54
+ # define the writer class method for the parameter
55
+ meta_def("#{name}=") do |value|
56
+ params[name].value = value
57
+ end
58
+
59
+ # define the getter/setter instance methods for the parameter
60
+ attr_accessor(name)
61
+ end
62
+
63
+ #
64
+ # Returns the class parameter with the specified _name_. If no
65
+ # such class parameter exists, a ParamNotFound exception will be
66
+ # raised.
67
+ #
68
+ def get_param(name)
69
+ name = name.to_sym
70
+
71
+ ancestors.each do |ancestor|
72
+ if ancestor.include?(Parameters)
73
+ if ancestor.params.has_key?(name)
74
+ return ancestor.params[name]
75
+ end
76
+ end
77
+ end
78
+
79
+ raise(ParamNotFound,"parameter #{name.to_s.dump} was not found in class #{self.name.dump}",caller)
80
+ end
81
+
82
+ #
83
+ # Returns +true+ if a class parameters with the specified _name_
84
+ # exists, returns +false+ otherwise.
85
+ #
86
+ def has_param?(name)
87
+ name = name.to_sym
88
+
89
+ ancestors.each do |ancestor|
90
+ if ancestor.include?(Parameters)
91
+ return true if ancestor.params.has_key?(name)
92
+ end
93
+ end
94
+
95
+ return false
96
+ end
97
+
98
+ #
99
+ # Iterates over all class parameters, passing each one to the
100
+ # specified _block_.
101
+ #
102
+ def each_param(&block)
103
+ ancestors.each do |ancestor|
104
+ if ancestor.include?(Parameters)
105
+ ancestor.params.each_value(&block)
106
+ end
107
+ end
108
+
109
+ return self
110
+ end
111
+
112
+ #
113
+ # Returns the description of the class parameters with the
114
+ # specified _name_. If no such class parameter exists, a
115
+ # ParamNotFound exception will be raised.
116
+ #
117
+ def describe_param(name)
118
+ get_param(name).description
119
+ end
120
+
121
+ #
122
+ # Returns the value of the class parameters with the specified
123
+ # _name_. If no such class parameter exists, a ParamNotFound
124
+ # exception will be raised.
125
+ #
126
+ def param_value(name)
127
+ get_param(name).value
128
+ end
129
+ end
130
+ end
131
+
132
+ #
133
+ # Initalizes the parameters of the object using the given
134
+ # _values_, which can override the default values of
135
+ # parameters.
136
+ #
137
+ def initialize_parameters
138
+ self.class.each_param do |param|
139
+ # do not override existing instance value if present
140
+ unless instance_variable_get("@#{param.name}")
141
+ begin
142
+ value = param.value.clone
143
+ rescue TypeError
144
+ value = param.value
145
+ end
146
+
147
+ instance_variable_set("@#{param.name}",value)
148
+ end
149
+
150
+ params[param.name] = InstanceParam.new(self,param.name,param.description)
151
+ end
152
+ end
153
+
154
+ #
155
+ # Initializes the parameters using initialize_parameters. If a +Hash+
156
+ # is passed in as the first argument, it will be used to set the values
157
+ # of parameters described within the Hash.
158
+ #
159
+ def initialize(*args,&block)
160
+ initialize_parameters
161
+
162
+ values = args.first
163
+
164
+ if values.kind_of?(Hash)
165
+ self.params = values
166
+ end
167
+ end
168
+
169
+ #
170
+ # Adds a new parameters with the specified _name_ and the given
171
+ # _options_ to the object.
172
+ #
173
+ # _options_ may contain the following keys:
174
+ # <tt>:description</tt>:: The description of the parameter.
175
+ # <tt>:default</tt>:: The default value the parameter will have.
176
+ #
177
+ # obj.parameter('var')
178
+ #
179
+ # obj.parameter('var',:default => 3, :description => 'my variable')
180
+ #
181
+ def parameter(name,options={})
182
+ name = name.to_sym
183
+
184
+ # set the instance variable
185
+ instance_variable_set("@#{name}",options[:default])
186
+
187
+ # add the new parameter
188
+ params[name] = InstanceParam.new(self,name,options[:description])
189
+
190
+ instance_eval %{
191
+ # define the reader method for the parameter
192
+ def #{name}
193
+ instance_variable_get("@#{name}")
194
+ end
195
+
196
+ # define the writer method for the parameter
197
+ def #{name}=(value)
198
+ instance_variable_set("@#{name}",value)
199
+ end
200
+ }
201
+
202
+ return params[name]
203
+ end
204
+
205
+ #
206
+ # Returns a +Hash+ of the classes params.
207
+ #
208
+ def class_params
209
+ self.class.params
210
+ end
211
+
212
+ #
213
+ # Returns a +Hash+ of the instance parameters.
214
+ #
215
+ def params
216
+ @params ||= {}
217
+ end
218
+
219
+ #
220
+ # Sets the values of the parameters described in the _values_ +Hash+.
221
+ #
222
+ # obj.params = {:x => 5, :y => 2}
223
+ # # => {:x=>5, :y=>2}
224
+ #
225
+ def params=(values)
226
+ values.each do |name,value|
227
+ if has_param?(name)
228
+ instance_variable_set("@#{name}",value)
229
+ end
230
+ end
231
+ end
232
+
233
+ #
234
+ # Returns +true+ if the a parameter with the specified _name_ exists,
235
+ # returns +false+ otherwise.
236
+ #
237
+ # obj.has_param?('rhost') # => true
238
+ #
239
+ def has_param?(name)
240
+ params.has_key?(name.to_sym)
241
+ end
242
+
243
+ #
244
+ # Returns the parameter with the specified _name_. If no such parameter
245
+ # exists, a ParamNotFound exception will be raised.
246
+ #
247
+ # obj.get_param('var') # => InstanceParam
248
+ #
249
+ def get_param(name)
250
+ name = name.to_sym
251
+
252
+ unless has_param?(name)
253
+ raise(ParamNotFound,"parameter #{name.to_s.dump} was not found within #{self.to_s.dump}",caller)
254
+ end
255
+
256
+ return params[name]
257
+ end
258
+
259
+ #
260
+ # Returns the description of the parameter with the specified _name_.
261
+ # If no such parameter exists, a ParamNotFound exception will be raised.
262
+ #
263
+ # obj.describe_param('rhost') # => "remote host"
264
+ #
265
+ def describe_param(name)
266
+ get_param(name).description
267
+ end
268
+
269
+ #
270
+ # Returns the value of the parameter with the specified _name_. If no
271
+ # such parameter exists, a ParamNotFound exception will be raised.
272
+ #
273
+ # obj.param_value('rhost') # => 80
274
+ #
275
+ def param_value(name)
276
+ get_param(name).value
277
+ end
278
+
279
+ #
280
+ # Sets the values of the parameters listed in the specified _values_.
281
+ #
282
+ # obj.set_params(:rhost => 'www.example.com', :rport => 80)
283
+ # # => {:rhost=>"www.example.com", :rport=>80}
284
+ #
285
+ def set_params(values={})
286
+ values.each do |name,value|
287
+ get_param(name).value = value
288
+ end
289
+ end
290
+ end
@@ -0,0 +1,3 @@
1
+ module Parameters
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,129 @@
1
+ require 'parameters'
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Parameters do
6
+ before(:all) do
7
+ class TestParameters
8
+ include Parameters
9
+
10
+ parameter :var, :description => 'Test parameter'
11
+
12
+ parameter :var_with_default,
13
+ :default => 'thing',
14
+ :description => 'This parameter has a default value'
15
+
16
+ end
17
+
18
+ class InheritedParameters < TestParameters
19
+
20
+ parameter :child_var, :description => 'Child parameter'
21
+
22
+ end
23
+ end
24
+
25
+ describe "in a Class" do
26
+ it "should provide parameters" do
27
+ TestParameters.params.should_not be_empty
28
+ end
29
+
30
+ it "can have default values for parameters" do
31
+ TestParameters.param_value(:var_with_default).should == 'thing'
32
+ end
33
+
34
+ it "should provide class methods for paremters" do
35
+ TestParameters.var = 1
36
+ TestParameters.var.should == 1
37
+ end
38
+
39
+ it "should inherite the super-classes parameters" do
40
+ InheritedParameters.has_param?(:var).should == true
41
+ InheritedParameters.has_param?(:child_var).should == true
42
+ end
43
+
44
+ it "should provide direct access to the parameter objects" do
45
+ param = TestParameters.get_param(:var)
46
+
47
+ param.should_not be_nil
48
+ param.name.should == :var
49
+ end
50
+
51
+ it "raise a ParamNotFound exception when directly accessing non-existent parameter objects" do
52
+ lambda { TestParameters.get_param(:unknown) }.should raise_error(Parameters::ParamNotFound)
53
+ end
54
+
55
+ it "should provide descriptions for parameters" do
56
+ TestParameters.describe_param(:var).should_not be_empty
57
+ end
58
+
59
+ it "should be able to create an object with initial parameter values" do
60
+ obj = TestParameters.new(:var => 2, :var_with_default => 'stuff')
61
+
62
+ obj.var.should == 2
63
+ obj.var_with_default.should == 'stuff'
64
+ end
65
+ end
66
+
67
+ describe "in an Object" do
68
+ before(:all) do
69
+ @test = TestParameters.new
70
+ @test_inherited = InheritedParameters.new
71
+ end
72
+
73
+ it "should provide direct access to all parameters" do
74
+ @test.params[:var].should_not be_nil
75
+ @test.params[:var_with_default].should_not be_nil
76
+ end
77
+
78
+ it "should allow for mass assignment of parameters" do
79
+ test2 = TestParameters.new
80
+ test2.params = {:var => 5, :var_with_default => 'hello'}
81
+
82
+ test2.var.should == 5
83
+ test2.var_with_default.should == 'hello'
84
+ end
85
+
86
+ it "can have default values for parameters" do
87
+ @test.param_value(:var_with_default).should == 'thing'
88
+ end
89
+
90
+ it "should provide instance methods for parameters" do
91
+ @test.var = 2
92
+ @test.var.should == 2
93
+ end
94
+
95
+ it "should set instance variables for paramters" do
96
+ @test.instance_variable_get('@var_with_default').should == 'thing'
97
+
98
+ @test.var = 3
99
+ @test.instance_variable_get('@var').should == 3
100
+ end
101
+
102
+ it "should contain the parameters from all ancestors" do
103
+ @test_inherited.has_param?(:var).should == true
104
+ @test_inherited.has_param?(:child_var).should == true
105
+ end
106
+
107
+ it "should provide direct access to the parameter objects" do
108
+ @param = @test.get_param(:var)
109
+
110
+ @param.should_not be_nil
111
+ @param.name.should == :var
112
+ end
113
+
114
+ it "should raise a ParamNotFound exception when directly accessing non-existent parameter objects" do
115
+ lambda { @test.get_param(:unknown) }.should raise_error(Parameters::ParamNotFound)
116
+ end
117
+
118
+ it "should allow for setting parameters en-mass" do
119
+ @test.set_params(:var => 3, :var_with_default => 7)
120
+
121
+ @test.param_value(:var).should == 3
122
+ @test.param_value(:var_with_default).should == 7
123
+ end
124
+
125
+ it "should provide descriptions for parameters" do
126
+ @test.describe_param(:var).should_not be_empty
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,5 @@
1
+ require 'rubygems'
2
+ gem 'rspec', '>=1.1.3'
3
+ require 'spec'
4
+
5
+ require 'parameters/version'
@@ -0,0 +1,9 @@
1
+ require 'spec/rake/spectask'
2
+
3
+ desc "Run all specifications"
4
+ Spec::Rake::SpecTask.new(:spec) do |t|
5
+ t.libs += ['lib', 'spec']
6
+ t.spec_opts = ['--colour', '--format', 'specdoc']
7
+ end
8
+
9
+ task :default => :spec
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: parameters
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Postmodern
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-12-03 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hoe
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.8.2
24
+ version:
25
+ description: Parameters allows you to add annoted variables to your classes which may have configurable default values.
26
+ email:
27
+ - postmodern.mod3@gmail.com
28
+ executables: []
29
+
30
+ extensions: []
31
+
32
+ extra_rdoc_files:
33
+ - History.txt
34
+ - Manifest.txt
35
+ - README.txt
36
+ files:
37
+ - History.txt
38
+ - Manifest.txt
39
+ - README.txt
40
+ - Rakefile
41
+ - lib/parameters.rb
42
+ - lib/parameters/exceptions.rb
43
+ - lib/parameters/exceptions/missing_param.rb
44
+ - lib/parameters/exceptions/param_not_found.rb
45
+ - lib/parameters/extensions.rb
46
+ - lib/parameters/extensions/meta.rb
47
+ - lib/parameters/extensions/meta/object.rb
48
+ - lib/parameters/class_param.rb
49
+ - lib/parameters/instance_param.rb
50
+ - lib/parameters/param.rb
51
+ - lib/parameters/parameters.rb
52
+ - lib/parameters/version.rb
53
+ - tasks/spec.rb
54
+ - spec/spec_helper.rb
55
+ - spec/parameters_spec.rb
56
+ has_rdoc: true
57
+ homepage: http://parameters.rubyforge.org/
58
+ post_install_message:
59
+ rdoc_options:
60
+ - --main
61
+ - README.txt
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ version:
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: "0"
75
+ version:
76
+ requirements: []
77
+
78
+ rubyforge_project: parameters
79
+ rubygems_version: 1.3.1
80
+ signing_key:
81
+ specification_version: 2
82
+ summary: Parameters allows you to add annoted variables to your classes which may have configurable default values.
83
+ test_files: []
84
+