named-parameters 0.0.7 → 0.0.8

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.
data/README.md CHANGED
@@ -1,15 +1,7 @@
1
1
  This gem simulates named-parameters in Ruby. It's a complement to the common
2
2
  Ruby idiom of using `Hash` args to emulate the use of named parameters.
3
3
 
4
- It does this by extending the language with a `has_named_parameters` clause
5
- that allows a class to declare the parameters that are acceptable to a method.
6
-
7
- The `has_named_parameters` dictates how the presence of these parameters are
8
- enforced and raises an `ArgumentError` when a method invocation is made that
9
- violates the rules for those parameters.
10
-
11
- See: the [Named Parameter](http://en.wikipedia.org/wiki/named_parameter)
12
- article from Wikipedia for more information.
4
+ Related: [Named Parameters in Ruby](http://www.jurisgalang.com/2010/11/09/named-parameters-in-ruby/)
13
5
 
14
6
  Get It
15
7
  ------
@@ -95,7 +87,7 @@ And is applicable to both class and instance methods:
95
87
  # ... do send mail stuff here ...
96
88
  end
97
89
 
98
- has_named_parameters :archive, :optional => [ :method => 'zip' ]
90
+ has_named_parameters :'self.archive', :optional => [ :method => 'zip' ]
99
91
  def self.archive options = { }
100
92
  # ... do mail archiving stuff here ...
101
93
  end
@@ -104,23 +96,25 @@ And is applicable to both class and instance methods:
104
96
  Shortcuts
105
97
  ---------
106
98
  In addition to the `has_named_parameters` method, `NamedParameters` also comes
107
- with two convenience methods for applying a parameter spec for constructors:
99
+ with two convenience methods for implicitly applying parameter specs for
100
+ constructors.
108
101
 
109
- Use the **`requires`** clause to declare what parameters a class expects when it
102
+ Use the `requires` clause to declare what parameters a class expects when it
110
103
  is instantiated:
111
104
 
112
105
  class GoogleStorage
113
- requires [ :'access-key', :'secret-key' ]
106
+ requires :'access-key', :'secret-key'
114
107
 
115
108
  def initialize options
116
109
  # ... do googly stuff here ...
117
110
  end
118
111
  end
119
112
 
120
- Use the **`recognizes`** clause to specify optional parameters for constructors:
113
+ Use the `recognizes` clause to specify the optional parameters for a class
114
+ when it is instantiated:
121
115
 
122
116
  class GoogleStorage
123
- recognizes [ :'group-email', :'apps-domain' ]
117
+ recognizes :'group-email', :'apps-domain'
124
118
 
125
119
  def initialize options
126
120
  # ... do googly stuff here ...
@@ -130,14 +124,22 @@ Use the **`recognizes`** clause to specify optional parameters for constructors:
130
124
  You may also specify default values for parameters when using these clauses:
131
125
 
132
126
  class GoogleStorage
133
- requires [ :'access-key', :'secret-key' ]
134
- recognizes [ [ :'group-email', 'group@example.org' ], [ :'apps-domain', 'example.org' ] ]
127
+ requires :'access-key', :'secret-key'
128
+ recognizes [ :'group-email', 'group@example.org' ], [ :'apps-domain', 'example.org' ]
135
129
 
136
130
  def initialize options
137
131
  # ... do googly stuff here ...
138
132
  end
139
133
  end
140
134
 
135
+ The `requires` and `recognizes` clause is equivalent to declaring the lines
136
+ in a class definition:
137
+
138
+ has_named_parameters :'self.new', :required => params, :strict
139
+ has_named_parameters :initialize, :required => params, :strict
140
+ has_named_parameters :'self.new', :optional => params, :strict
141
+ has_named_parameters :initialize, :optional => params, :strict
142
+
141
143
  Permissive Mode
142
144
  ---------------
143
145
  When a method is declared with `has_named_parameters` that method will only
@@ -173,15 +175,15 @@ The `:required` and `:oneof` parameters will still be expected:
173
175
  For clarity you should skip the `:optional` parameters list altogether when
174
176
  using the `:permissive` mode.
175
177
 
176
- The `requires` and `recognizes` clause for constructors will also accept a
177
- `mode` setting:
178
+ However, the `requires` and `recognizes` clauses does not accept the `mode` argument.
179
+ If you need to make a constructor's optional parameter spec permissive, use
180
+ the `has_named_parameters` clause instead:
178
181
 
179
- requires [ :x ], :permissive
180
- recognizes [ :y, :z ], :permissive
182
+ has_named_parameters :'self.new', :required => params, :permissive
183
+ has_named_parameters :initialize, :required => params, :permissive
181
184
 
182
- And just like the `:optional` parameter list in the `has_named_parameters`
183
- clause, when `:permissive` mode is used, it's clearer to omit the `recognizes`
184
- clause altogether.
185
+ For brevity, since the mode is `:permissive`, the `:optional` parameters list
186
+ is skipped.
185
187
 
186
188
  How It Works
187
189
  ------------
@@ -246,6 +248,69 @@ For the above case, it might be better to refactor:
246
248
 
247
249
  # result:
248
250
  # => path: /xxx, options: {}
251
+
252
+ Class vs Instance Methods
253
+ -------------------------
254
+ Parameter spec declarations are not shared between class and instance
255
+ methods even if they share the same name.
256
+
257
+ For example, the following `has_named_parameters` declaration below is only
258
+ applicable to the instance method `exec`:
259
+
260
+ class Command
261
+ has_named_parameters :exec, :required => :x
262
+ def self.exec opts
263
+ # ...
264
+ end
265
+
266
+ def exec opts
267
+ # ...
268
+ end
269
+ end
270
+
271
+ # the following will *not* raise an ArgumentError because
272
+ # the has_named_parameter declaration applies only to the
273
+ # instance method exec...
274
+ Command.exec
275
+
276
+ # the following will raise an ArgumentError (as expected)
277
+ command = Command.new
278
+ command.exec
279
+
280
+ Prefix the method name with `self.` to apply parameter spec for class methods:
281
+
282
+ class Command
283
+ has_named_parameters :'self.exec', :required => :x
284
+ def self.exec opts
285
+ # ...
286
+ end
287
+ end
288
+
289
+ # the following will now raise an ArgumentError (as expected)
290
+ Command.exec
291
+
292
+ In general, however, when a class has an instance and a class method using
293
+ the same name, for most cases, one simply delegates to another and will share
294
+ the same requirements. So the examples cited above can be refactored:
295
+
296
+ class Command
297
+ has_named_parameters :'self.exec', :required => :x
298
+ def self.exec opts
299
+ # ...
300
+ end
301
+
302
+ def exec opts
303
+ Command.exec
304
+ end
305
+ end
306
+
307
+ # the following will raise an ArgumentError (as expected)
308
+ Command.exec
309
+
310
+ # the following will also raise an ArgumentError as it delegates to the
311
+ # class method and violates the parameter requirements
312
+ command = Command.new
313
+ command.exec
249
314
 
250
315
  Dependencies
251
316
  ------------
@@ -1,3 +1,11 @@
1
+ 0.0.8 [Nov 22, 2010]
2
+ - [INTERNAL] Parameter spec will no longer be shared between singleton and
3
+ instance methods. Bonus performance improvement: it no longer needs to keep
4
+ track of the parameter specs after the class is declared.
5
+ - [INTERNAL] The mode argument is no longer entertained by the requires and
6
+ recognizes clause. Use the has_named_parameters clause on constructors if
7
+ permissive behavior is required on optional parameters.
8
+
1
9
  0.0.7 [Nov 18, 2010]
2
10
  - [FEATURE] Added support to distinguish named parameters declaration for
3
11
  class and instance methods that uses the same names. So now you could do:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.7
1
+ 0.0.8
@@ -122,45 +122,35 @@ module NamedParameters
122
122
 
123
123
  # Convenience method, equivalent to declaring:
124
124
  #
125
- # has_named_parameters :'self.new', :required => params
126
- # has_named_parameters :initialize, :required => params
125
+ # has_named_parameters :'self.new', :required => params, :strict
126
+ # has_named_parameters :initialize, :required => params, :strict
127
127
  #
128
128
  # @param [Array] params the lists of parameters. The list is expected
129
129
  # to be an `Array` of symbols matching the names of the required
130
130
  # parameters.
131
131
  #
132
- # @param [Symbol] mode enforces that only parameters that were named in
133
- # either the `:required`, `:optional`, and `:oneof` list may be allowed.
134
- # Set it to `:permissive` to relax the requirement - `:required` and `:oneof`
135
- # parameters will still be expected.
136
- #
137
- def requires params, mode = :strict
138
- [ :new, :initialize ].each do |method|
132
+ def requires *params
133
+ [ :'self.new', :initialize ].each do |method|
139
134
  spec = specs[key_for method] || { }
140
135
  spec.merge!(:required => params)
141
- has_named_parameters method, spec, mode
136
+ has_named_parameters method, spec, :strict
142
137
  end
143
138
  end
144
139
 
145
140
  # Convenience method, equivalent to declaring:
146
141
  #
147
- # has_named_parameters :'self.new', :optional => params
148
- # has_named_parameters :initialize, :optional => params
142
+ # has_named_parameters :'self.new', :optional => params, :strict
143
+ # has_named_parameters :initialize, :optional => params, :strict
149
144
  #
150
145
  # @param [Array] params the lists of parameters. The list is expected
151
146
  # to be an `Array` of symbols matching the names of the optional
152
147
  # parameters.
153
148
  #
154
- # @param [Symbol] mode enforces that only parameters that were named in
155
- # either the `:required`, `:optional`, and `:oneof` list may be allowed.
156
- # Set it to `:permissive` to relax the requirement - `:required` and `:oneof`
157
- # parameters will still be expected.
158
- #
159
- def recognizes params, mode = :strict
160
- [ :new, :initialize ].each do |method|
149
+ def recognizes *params
150
+ [ :'self.new', :initialize ].each do |method|
161
151
  spec = specs[key_for method] || { }
162
152
  spec.merge!(:optional => params)
163
- has_named_parameters method, spec, mode
153
+ has_named_parameters method, spec, :strict
164
154
  end
165
155
  end
166
156
 
@@ -193,15 +183,15 @@ module NamedParameters
193
183
  # ...
194
184
  # end
195
185
  #
196
- def validates_arguments method, param, &block
197
- # TODO: IMPLEMENT
198
- end
186
+ #def validates_arguments method, param, &block
187
+ # # TODO: IMPLEMENT
188
+ #end
199
189
 
200
190
  # add instrumentation for class methods
201
191
  def singleton_method_added name # :nodoc:
202
- instrument name do
192
+ instrument :"self.#{name}" do
203
193
  method = self.eigenclass.instance_method name
204
- spec = specs[key_for :"self.#{name}"] || specs[key_for name]
194
+ spec = specs.delete(key_for :"self.#{name}")
205
195
  owner = "#{self.name}::"
206
196
  eigenclass.instance_eval do
207
197
  intercept method, owner, name, spec
@@ -214,7 +204,7 @@ module NamedParameters
214
204
  def method_added name # :nodoc:
215
205
  instrument name do
216
206
  method = instance_method name
217
- spec = specs[key_for name] || specs[key_for :"self.#{name}"]
207
+ spec = specs.delete(key_for name)
218
208
  owner = "#{self.name}#"
219
209
  intercept method, owner, name, spec
220
210
  end
@@ -1,15 +1,15 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{named-parameters}
8
- s.version = "0.0.7"
8
+ s.version = "0.0.8"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Juris Galang"]
12
- s.date = %q{2010-11-18}
12
+ s.date = %q{2010-11-22}
13
13
  s.description = %q{This gem simulates named-parameters in Ruby. It's a complement to the common
14
14
  Ruby idiom of using `Hash` args to emulate the use of named parameters.
15
15
 
@@ -26,29 +26,27 @@ Gem::Specification.new do |s|
26
26
  ]
27
27
  s.files = [
28
28
  ".document",
29
- ".gitignore",
30
- "GPL-LICENSE",
31
- "MIT-LICENSE",
32
- "README.md",
33
- "RELEASENOTES",
34
- "Rakefile",
35
- "VERSION",
36
- "lib/named-parameters.rb",
37
- "lib/named-parameters/module.rb",
38
- "lib/named-parameters/object.rb",
39
- "named-parameters.gemspec",
40
- "spec/named-parameters_spec.rb",
41
- "spec/spec.opts",
42
- "spec/spec_helper.rb"
29
+ "GPL-LICENSE",
30
+ "MIT-LICENSE",
31
+ "README.md",
32
+ "RELEASENOTES",
33
+ "Rakefile",
34
+ "VERSION",
35
+ "lib/named-parameters.rb",
36
+ "lib/named-parameters/module.rb",
37
+ "lib/named-parameters/object.rb",
38
+ "named-parameters.gemspec",
39
+ "spec/named-parameters_spec.rb",
40
+ "spec/spec.opts",
41
+ "spec/spec_helper.rb"
43
42
  ]
44
43
  s.homepage = %q{http://github.com/jurisgalang/named-parameters}
45
- s.rdoc_options = ["--charset=UTF-8"]
46
44
  s.require_paths = ["lib"]
47
45
  s.rubygems_version = %q{1.3.7}
48
46
  s.summary = %q{Poor man's named-parameters in Ruby}
49
47
  s.test_files = [
50
48
  "spec/named-parameters_spec.rb",
51
- "spec/spec_helper.rb"
49
+ "spec/spec_helper.rb"
52
50
  ]
53
51
 
54
52
  if s.respond_to? :specification_version then
@@ -1,17 +1,20 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
+ # TODO: reorganize the tests for clarity
4
+ # TODO: need separate spec for the NamedParameters.validate_specs method
5
+ # TODO: factor out specs for required, recognizes, and has_named_parameters
3
6
  describe "NamedParameters" do
4
7
  before :all do
5
8
  class Foo
6
9
  has_named_parameters :initialize, :required => :x, :optional => [ :y, :z ]
7
10
  def initialize opts = {}; end
8
-
11
+
9
12
  has_named_parameters :method_one, :required => :x, :optional => [ :y, :z ]
10
13
  def method_one x, y, opts = {}; end
11
-
14
+
12
15
  def method_two x, y, opts = {}; end
13
16
 
14
- has_named_parameters :method_three, :required => :x, :optional => [ :y, :z ]
17
+ has_named_parameters :'self.method_three', :required => :x, :optional => [ :y, :z ]
15
18
  def self.method_three x, y, opts = {}; end
16
19
 
17
20
  def self.method_four x, y, opts = {}; end
@@ -35,7 +38,7 @@ describe "NamedParameters" do
35
38
 
36
39
  has_named_parameters :method_with_many_optional, :optional => [ :x, :y ]
37
40
  def method_with_many_optional opts = {}; end
38
-
41
+
39
42
  has_named_parameters :method_with_one_of_each_requirement, :required => :w, :oneof => [ :x, :y ], :optional => :z
40
43
  def method_with_one_of_each_requirement opts = {}; end
41
44
  end
@@ -52,7 +55,7 @@ describe "NamedParameters" do
52
55
  lambda{ Foo.new :x => :x, :y => :y }.should_not raise_error
53
56
  lambda{ Foo.new :x => :x, :y => :y, :z => :z }.should_not raise_error
54
57
  end
55
-
58
+
56
59
  it "should enforce named parameters for instrumented instance methods" do
57
60
  lambda{ @foo = Foo.new :x => :x, :y => :y, :z => :z }.should_not raise_error
58
61
  lambda{ @foo.method_one :x }.should raise_error ArgumentError
@@ -64,7 +67,7 @@ describe "NamedParameters" do
64
67
  lambda{ @foo.method_one :x, :y, :x => :x, :y => :y }.should_not raise_error
65
68
  lambda{ @foo.method_one :x, :y, :x => :x, :y => :y, :z => :z }.should_not raise_error
66
69
  end
67
-
70
+
68
71
  it "should not enforce named parameters for un-instrumented instance methods" do
69
72
  lambda{ @foo = Foo.new :x => :x, :y => :y, :z => :z }.should_not raise_error
70
73
  lambda{ @foo.method_two :x }.should raise_error ArgumentError
@@ -135,15 +138,15 @@ describe "NamedParameters" do
135
138
  lambda{ bar.method_with_one_of_each_requirement :w => :w, :y => :y, :z => :z }.should_not raise_error
136
139
  lambda{ bar.method_with_one_of_each_requirement :w => :w, :x => :x, :z => :z, :a => :a }.should raise_error ArgumentError
137
140
  end
138
-
141
+
139
142
  it "should be able to supply the default values for optional parameters" do
140
143
  class Zoo
141
144
  has_named_parameters :method_with_one_optional_parameter, :optional => { :x => 1 }
142
145
  def method_with_one_optional_parameter opts = { }; opts[:x]; end
143
-
146
+
144
147
  has_named_parameters :method_with_many_optional_parameters, :optional => [ [ :x, 1 ], [ :y, 2 ] ]
145
148
  def method_with_many_optional_parameters opts = { }; opts[:x] + opts[:y]; end
146
-
149
+
147
150
  has_named_parameters :method_with_many_optional_parameters_too, :optional => [ { :x => 1 }, { :y => 2 } ]
148
151
  def method_with_many_optional_parameters_too opts = { }; opts[:x] + opts[:y]; end
149
152
  end
@@ -151,11 +154,11 @@ describe "NamedParameters" do
151
154
  zoo = Zoo.new
152
155
  zoo.method_with_one_optional_parameter.should eql 1
153
156
  zoo.method_with_one_optional_parameter(:x => 2).should eql 2
154
-
157
+
155
158
  zoo.method_with_many_optional_parameters.should eql 3
156
159
  zoo.method_with_many_optional_parameters(:x => 2).should eql 4
157
160
  zoo.method_with_many_optional_parameters(:x => 2, :y => 3).should eql 5
158
-
161
+
159
162
  zoo.method_with_many_optional_parameters_too.should eql 3
160
163
  zoo.method_with_many_optional_parameters_too(:x => 2).should eql 4
161
164
  zoo.method_with_many_optional_parameters_too(:x => 2, :y => 3).should eql 5
@@ -163,8 +166,10 @@ describe "NamedParameters" do
163
166
 
164
167
  it "should be able to instrument the class method new" do
165
168
  class Quux
166
- has_named_parameters :new, :required => :x
167
- def self.new opts = { }; end
169
+ has_named_parameters :'self.new', :required => :x
170
+ class << self
171
+ def new opts = { }; end
172
+ end
168
173
  def initialize opts = { }; end
169
174
  end
170
175
  lambda { Quux.new }.should raise_error ArgumentError
@@ -175,7 +180,7 @@ describe "NamedParameters" do
175
180
 
176
181
  it "should be able to specify optional parameters using the recognizes method" do
177
182
  class Recognizes
178
- recognizes [ :x, :y ]
183
+ recognizes :x, :y
179
184
  def self.new opts = { }; end
180
185
  def initialize opts = { }; end
181
186
  end
@@ -185,10 +190,10 @@ describe "NamedParameters" do
185
190
  lambda { Recognizes.new :x => :x, :y => :y }.should_not raise_error
186
191
  lambda { Recognizes.new :z => :z }.should raise_error ArgumentError
187
192
  end
188
-
193
+
189
194
  it "should be able to specify required parameters using the recognizes method" do
190
195
  class Required
191
- requires [ :x, :y ]
196
+ requires :x, :y
192
197
  def self.new opts = { }; end
193
198
  def initialize opts = { }; end
194
199
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: named-parameters
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 7
10
- version: 0.0.7
9
+ - 8
10
+ version: 0.0.8
11
11
  platform: ruby
12
12
  authors:
13
13
  - Juris Galang
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-18 00:00:00 -08:00
18
+ date: 2010-11-22 00:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -58,7 +58,6 @@ extra_rdoc_files:
58
58
  - README.md
59
59
  files:
60
60
  - .document
61
- - .gitignore
62
61
  - GPL-LICENSE
63
62
  - MIT-LICENSE
64
63
  - README.md
@@ -77,8 +76,8 @@ homepage: http://github.com/jurisgalang/named-parameters
77
76
  licenses: []
78
77
 
79
78
  post_install_message:
80
- rdoc_options:
81
- - --charset=UTF-8
79
+ rdoc_options: []
80
+
82
81
  require_paths:
83
82
  - lib
84
83
  required_ruby_version: !ruby/object:Gem::Requirement
data/.gitignore DELETED
@@ -1,21 +0,0 @@
1
- ## MAC OS
2
- .DS_Store
3
-
4
- ## TEXTMATE
5
- *.tmproj
6
- tmtags
7
-
8
- ## EMACS
9
- *~
10
- \#*
11
- .\#*
12
-
13
- ## VIM
14
- *.swp
15
-
16
- ## PROJECT::GENERAL
17
- coverage
18
- rdoc
19
- pkg
20
-
21
- ## PROJECT::SPECIFIC