named-parameters 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -2,6 +2,9 @@ NamedParameters Gem
2
2
  ===================
3
3
  This gem enables/simulates named-parameters in Ruby.
4
4
 
5
+ See: http://en.wikipedia.org/wiki/named_parameter for more information on
6
+ Named Parameters in general.
7
+
5
8
  Installation
6
9
  ------------
7
10
 
@@ -53,14 +56,14 @@ invocation will (correctly) raise an `ArgumentError`
53
56
 
54
57
  GoogleStorage.new # ArgumentError, GoogleStorage#initialize requires: access-key, secret-key
55
58
 
56
- On the other-hand, it declares that the `request` method may accept a parameter
57
- named `timeout`; so the following invocations will not raise error:
59
+ On the other-hand, it declares that the `request` method may optionally accept
60
+ a parameter named `timeout` - so the following invocations will not raise error:
58
61
 
59
62
  gs = GoogleStorage.new :'access-key' => '...', :'secret-key' => '...'
60
63
  gs.request '/some/path'
61
64
  gs.request '/some/path', :timeout => '500ms'
62
65
 
63
- But specifiying an unrecognized parameter, will raise an error:
66
+ But specifying an unrecognized parameter will do:
64
67
 
65
68
  gs.request '/some/path', :ssl => true # ArgumentError, GoogleStorage#request unrecognized parameter: ssl
66
69
 
@@ -82,7 +85,7 @@ argument when a method that has been declared with `has_named_parameters` is
82
85
  called.
83
86
 
84
87
  It does not know the name of the `Hash` parameter for the method. So the
85
- following method declarations:
88
+ following variations:
86
89
 
87
90
  def service opts = { }
88
91
  # ...
data/RELEASENOTES CHANGED
@@ -1,3 +1,7 @@
1
+ 0.0.3 [Nov 11, 2010]
2
+ --------------------
3
+ - Added support for has_named_parameter declaration for class methods.
4
+
1
5
  0.0.2 [Nov 10, 2010]
2
6
  --------------------
3
7
  - [BUGFIX] ArgumentError incorrectly references Module instead of actual class
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.3
@@ -15,13 +15,24 @@
15
15
  # FooBar.new :x => '...' # instantiates FooBar
16
16
  # FooBar.new :y => '...' # ArgumentError - since :x was not specified
17
17
  #
18
+ # @author Juris Galang
19
+ #
20
+ class Object
21
+ def eigenclass # :nodoc:
22
+ class << self; self; end
23
+ end
24
+ end
25
+
18
26
  module NamedParameters
19
- def self.included base
27
+ def self.included base # :nodoc:
20
28
  base.extend ClassMethods
21
29
  end
22
30
 
23
31
  private
24
- def self.validate name, params, spec
32
+ # this is the method used to validate the name of the received parameters
33
+ # (based on the defined spec) when an instrumented method is invoked.
34
+ #
35
+ def self.validate name, params, spec # :nodoc:
25
36
  spec[:required] ||= []
26
37
  spec[:optional] ||= []
27
38
 
@@ -54,36 +65,83 @@ module NamedParameters
54
65
 
55
66
  module ClassMethods
56
67
  protected
57
- def method_added name
58
- if specs.include?(name) && !instrumenting?
59
- @instrumenting = true
60
- method = instance_method(name)
61
- spec = specs.delete(name)
62
- define_method name do |*args, &block|
63
- params = args.find{ |arg| arg.instance_of? Hash }
64
- name = "#{self.class.name}##{name}"
65
- NamedParameters::validate name, params || {}, spec
66
- method.bind(self).call(*args, &block)
68
+ # Declares that `method` will enforce named parameters behavior as
69
+ # described in `spec`; a method declared with `required` and/or `optional`
70
+ # parameters will raise an `ArgumentError` if it is invoked without its
71
+ # required parameters or receives an unrecognized parameter.
72
+ #
73
+ # Sample usage:
74
+ #
75
+ # has_named_parameters :point, :required => [ :x, :y ],
76
+ # :optional => :color
77
+ #
78
+ # @param [Symbol] `method` the name of the method that is supposed to
79
+ # enforce named parameters behavior.
80
+ #
81
+ # @param [Hash] `spec` the list of required and optional parameters.
82
+ #
83
+ # @return [Hash] the specified `spec`
84
+ #
85
+ def has_named_parameters method, spec = { }
86
+ specs[method] = spec
87
+ end
88
+
89
+ # add instrumentation for class methods
90
+ def singleton_method_added name # :nodoc:
91
+ instrument name do
92
+ method = self.eigenclass.instance_method name
93
+ spec = specs.delete name
94
+ owner = "#{self.name}."
95
+ eigenclass.instance_eval do
96
+ intercept method, owner, name, spec
67
97
  end
68
- @instrumenting = false
98
+ end
99
+ super
100
+ end
101
+
102
+ # add instrumentation for instance methods
103
+ def method_added name # :nodoc:
104
+ instrument name do
105
+ method = instance_method name
106
+ spec = specs.delete name
107
+ owner = "#{self.name}#"
108
+ intercept method, owner, name, spec
69
109
  end
70
110
  super
71
111
  end
72
112
 
73
- def has_named_parameters method, spec = { }
74
- specs[method] = spec
113
+ private
114
+ # apply instrumentation to method
115
+ def instrument method # :nodoc:
116
+ if specs.include? method and !instrumenting?
117
+ @instrumenting = true
118
+ yield method
119
+ @instrumenting = false
120
+ end
75
121
  end
76
122
 
77
- private
78
- def specs
123
+ # insert parameter validation prior to executing the instrumented method
124
+ def intercept method, owner, name, spec # :nodoc:
125
+ define_method name do |*args, &block|
126
+ params = args.find{ |arg| arg.instance_of? Hash }
127
+ name = "#{owner}#{name}"
128
+ NamedParameters::validate name, params || {}, spec
129
+ method.bind(self).call(*args, &block)
130
+ end
131
+ end
132
+
133
+ # initialize specs table as needed
134
+ def specs # :nodoc:
79
135
  @specs ||= { }
80
136
  end
81
137
 
82
- def instrumenting?
138
+ # check if in the process of instrumenting a method
139
+ def instrumenting? # :nodoc:
83
140
  @instrumenting
84
141
  end
85
142
 
86
- def self.extended base
143
+ # initialize the @instrumenting instance variable (housekeeping)
144
+ def self.extended base # :nodoc:
87
145
  base.instance_variable_set :@instrumenting , false
88
146
  end
89
147
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{named-parameters}
8
- s.version = "0.0.2"
8
+ s.version = "0.0.3"
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-10}
12
+ s.date = %q{2010-11-11}
13
13
  s.description = %q{This gem enables/simulates named-parameters in Ruby}
14
14
  s.email = %q{jurisgalang@gmail.com}
15
15
  s.extra_rdoc_files = [
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: 27
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
9
+ - 3
10
+ version: 0.0.3
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-10 00:00:00 -08:00
18
+ date: 2010-11-11 00:00:00 -08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency