option_initializer 1.2.0 → 1.3.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.
data/README.md CHANGED
@@ -15,11 +15,9 @@ require 'option_initializer'
15
15
 
16
16
  class Person
17
17
  include OptionInitializer
18
- option_initializer :id, :name, :age, :greetings
18
+ option_initializer :id, :name, :greetings => :block, :birthday => 1..3
19
19
  option_validator do |k, v|
20
20
  case k
21
- when :age
22
- raise ArgumentError, "invalid age" if v < 0
23
21
  when :name
24
22
  raise ArgumentError, "invalid name" if v.empty?
25
23
  end
@@ -38,7 +36,7 @@ end
38
36
  # Then
39
37
  john = Person.
40
38
  name('John Doe').
41
- age(19).
39
+ birthday(1990, 1, 1).
42
40
  greetings { |name| "Hi, I'm #{name}!" }.
43
41
  id(1000).
44
42
  new
@@ -47,7 +45,7 @@ john = Person.
47
45
  john = Person.new(
48
46
  :id => 1000,
49
47
  :name => 'John Doe',
50
- :age => 19,
48
+ :birthday => [1990, 1, 1],
51
49
  :greetings => proc { |name| "Hi, I'm #{name}!" }
52
50
  )
53
51
 
@@ -1,3 +1,3 @@
1
1
  module OptionInitializer
2
- VERSION = "1.2.0"
2
+ VERSION = "1.3.0"
3
3
  end
@@ -97,43 +97,74 @@ module OptionInitializer
97
97
  def base.option_initializer *syms
98
98
  oi = self.const_get(:OptionInitializing)
99
99
 
100
+ pairs = syms.inject([]) { |arr, sym|
101
+ case sym
102
+ when Symbol, String
103
+ arr << [sym.to_sym, 1]
104
+ when Hash
105
+ arr.concat sym.map { |k, v|
106
+ unless (v.is_a?(Fixnum) && v > 0) || (v.is_a?(Range) && v.begin > 0) || v == :block
107
+ raise ArgumentError, "invalid number of arguments specified for #{k}"
108
+ end
109
+ [k.to_sym, v]
110
+ }
111
+ else
112
+ raise ArgumentError, "invalid option specification"
113
+ end
114
+ }
115
+
100
116
  # Class methods
101
- syms.each do |sym|
117
+ pairs.each do |pair|
118
+ sym = pair.first
119
+
102
120
  self.class_eval do
103
121
  # define_singleton_method not available on 1.8
104
122
  singleton = class << self; self end
105
123
  singleton.send :undef_method, sym if singleton.method_defined?(sym)
106
124
  singleton.send :define_method, sym do |*v, &b|
107
- if b && v.empty?
108
- oi.new self, {sym => b}, true
109
- elsif b && !v.empty?
110
- raise ArgumentError,
111
- "wrong number of arguments (#{v.length} for 0 when block given)"
112
- elsif v.length == 1
113
- oi.new self, {sym => v.first}, true
114
- else
115
- raise ArgumentError,
116
- "wrong number of arguments (#{v.length} for 1)"
117
- end
125
+ oi.new(self, {}, false).send(sym, *v, &b)
118
126
  end
119
127
  end
120
128
  end
121
129
 
122
130
  # Instance methods
123
131
  oi.class_eval do
124
- syms.each do |sym|
132
+ pairs.each do |pair|
133
+ sym, nargs = pair
125
134
  undef_method(sym) if method_defined?(sym)
126
135
  define_method(sym) do |*v, &b|
127
- if b && v.empty?
128
- merge(sym => b)
129
- elsif b && !v.empty?
130
- raise ArgumentError,
131
- "wrong number of arguments (#{v.length} for 0 when block given)"
132
- elsif v.length == 1
133
- merge(sym => v.first)
136
+ case nargs
137
+ when :block
138
+ if b
139
+ if v.empty?
140
+ merge(sym => b)
141
+ else
142
+ raise ArgumentError, "only block expected"
143
+ end
144
+ else
145
+ raise ArgumentError, "block expected but not given"
146
+ end
147
+ when 1
148
+ if b && v.empty?
149
+ merge(sym => b)
150
+ elsif b && !v.empty?
151
+ raise ArgumentError, "wrong number of arguments (#{v.length} for 0 when block given)"
152
+ elsif v.length == 1
153
+ merge(sym => v.first)
154
+ else
155
+ raise ArgumentError, "wrong number of arguments (#{v.length} for 1)"
156
+ end
157
+ when Range, Fixnum
158
+ if b
159
+ raise ArgumentError, "block not expected"
160
+ elsif (nargs.is_a?(Range) && !nargs.include?(v.length)) ||
161
+ (nargs.is_a?(Fixnum) && nargs != v.length)
162
+ raise ArgumentError, "wrong number of arguments (#{v.length} for #{nargs})"
163
+ else
164
+ merge(sym => v)
165
+ end
134
166
  else
135
- raise ArgumentError,
136
- "wrong number of arguments (#{v.length} for 1)"
167
+ raise ArgumentError, "invalid option specification"
137
168
  end
138
169
  end
139
170
  end
@@ -79,13 +79,37 @@ class MyClass3
79
79
  end
80
80
  end
81
81
 
82
+ class MyClass4
83
+ attr_reader :options
84
+
85
+ include OptionInitializer
86
+ option_initializer :two => 2,
87
+ :two_or_three => 2..3,
88
+ :yet_two_or_three => 2...4,
89
+ :b => :block
90
+
91
+ def initialize options
92
+ validate_options @options = options
93
+ end
94
+ end
95
+
96
+ class MyClass5
97
+ include OptionInitializer
98
+ end
99
+
82
100
  # Excerpt from README
83
101
  class Person
84
102
  include OptionInitializer
85
- option_initializer :id, :name, :age, :greetings
86
- option_initializer!
103
+ option_initializer! :id, :name, :greetings, :birthday => 1..3
104
+ option_validator do |k, v|
105
+ case k
106
+ when :name
107
+ raise ArgumentError, "invalid name" if v.empty?
108
+ end
109
+ end
87
110
 
88
111
  def initialize opts
112
+ validate_options opts
89
113
  @options = opts
90
114
  end
91
115
 
@@ -162,10 +186,46 @@ class TestOptionInitializer < MiniTest::Unit::TestCase
162
186
  assert_raises(TypeError) { MyClass2.new 'str' }
163
187
  end
164
188
 
189
+ def test_varargs
190
+ obj = MyClass4.two(1, 2).two_or_three(2, 3, 4).yet_two_or_three(3, 4, 5).b { :r }.new
191
+ assert_equal [1, 2], obj.options[:two]
192
+ assert_equal [2, 3, 4], obj.options[:two_or_three]
193
+ assert_equal [3, 4, 5], obj.options[:yet_two_or_three]
194
+ assert_equal :r, obj.options[:b].call
195
+ assert_raises(ArgumentError) { MyClass4.two(1) }
196
+ assert_raises(ArgumentError) { MyClass4.two(1, 2) { } }
197
+ assert_raises(ArgumentError) { MyClass4.two { } }
198
+ assert_raises(ArgumentError) { MyClass4.two_or_three(1) }
199
+ assert_raises(ArgumentError) { MyClass4.yet_two_or_three(1, 2, 3, 4) }
200
+ assert_raises(ArgumentError) { MyClass4.yet_two_or_three {} }
201
+ assert_raises(ArgumentError) { MyClass4.b(1) }
202
+ assert_raises(ArgumentError) { MyClass4.b(1) {} }
203
+ end
204
+
205
+ def test_varargs_def
206
+ assert_raises(NoMethodError) { MyClass5.a(1) }
207
+ MyClass5.class_eval do
208
+ option_initializer :a => 1...4
209
+ end
210
+ MyClass5.a(1)
211
+
212
+ assert_raises(ArgumentError) { MyClass5.class_eval { option_initializer :b => 0 } }
213
+ assert_raises(ArgumentError) { MyClass5.class_eval { option_initializer :b => 3.14 } }
214
+ assert_raises(ArgumentError) { MyClass5.class_eval { option_initializer :b => [1] } }
215
+ assert_raises(ArgumentError) { MyClass5.class_eval { option_initializer :b => 0..3 } }
216
+ assert_raises(ArgumentError) { MyClass5.class_eval { option_initializer 3.14 } }
217
+ assert_raises(ArgumentError) { MyClass5.class_eval { option_initializer 3.14 => nil } }
218
+ assert_raises(ArgumentError) { MyClass5.class_eval { option_initializer :b => :block? } }
219
+ end
220
+
165
221
  def test_readme
166
- john = Person.name('John Doe').age(19).greetings { |name| "Hi, I'm #{name}!" }.id(1000).new
167
- john = Person.new :id => 1000, :name => 'John Doe', :age => 19, :greetings => proc { |name| "Hi, I'm #{name}!" }
168
- Person.name('John Doe').age(19).greetings { |name| "Hi, I'm #{name}!" }.id(1000).say_hello
222
+ john = Person.name('John Doe').birthday(1990, 1, 1).
223
+ greetings { |name| "Hi, I'm #{name}!" }.id(1000).new
224
+ john = Person.new :id => 1000, :name => 'John Doe',
225
+ :birthday => [1990, 1, 1],
226
+ :greetings => proc { |name| "Hi, I'm #{name}!" }
227
+ Person.name('John Doe').birthday(1990, 1, 1).
228
+ greetings { |name| "Hi, I'm #{name}!" }.id(1000).say_hello
169
229
  end
170
230
  end
171
231
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: option_initializer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-04 00:00:00.000000000 Z
12
+ date: 2013-03-16 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Object construction with method chaining
15
15
  email: