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 +3 -5
- data/lib/option_initializer/version.rb +1 -1
- data/lib/option_initializer.rb +53 -22
- data/test/test_option_initializer.rb +65 -5
- metadata +2 -2
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, :
|
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
|
-
|
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
|
-
:
|
48
|
+
:birthday => [1990, 1, 1],
|
51
49
|
:greetings => proc { |name| "Hi, I'm #{name}!" }
|
52
50
|
)
|
53
51
|
|
data/lib/option_initializer.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
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, :
|
86
|
-
|
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').
|
167
|
-
|
168
|
-
Person.
|
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.
|
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-
|
12
|
+
date: 2013-03-16 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Object construction with method chaining
|
15
15
|
email:
|