abstractable 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +18 -1
- data/lib/abstractable.rb +23 -3
- data/lib/abstractable/version.rb +1 -1
- data/spec/abstractable_spec.rb +20 -3
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 438e87395388206c629f6329ecb65dd1e88f434f
|
4
|
+
data.tar.gz: c340f5981023a140b7f26558a7c5febf252bf878
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 272f4b8d513725c09eb2b5d7f1d88636ebaaac6f7e7cc5d6cf44a809e57d1415adb2388d2a6a3e929e72860bbf7680e82753c10694418d168066ed3029d0a3f5
|
7
|
+
data.tar.gz: 025e2700b437627788f86309d6bbeacba949e586755a794b0fb33468efb8bb2d3f5acbf5acea579cb0847271fe8d503de01e68d725c7a52b26d0e6694935fcab
|
data/README.md
CHANGED
@@ -175,19 +175,36 @@ Therefore throw error at abstract method call.
|
|
175
175
|
But can find unimplemented abstract methods.
|
176
176
|
```ruby
|
177
177
|
class AbstractParent
|
178
|
+
extend Abstractable
|
179
|
+
|
178
180
|
class << self
|
179
181
|
extend Abstractable
|
180
182
|
abstract :greet
|
181
183
|
end
|
182
184
|
end
|
183
185
|
|
184
|
-
class
|
186
|
+
class AbstractChild < AbstractParent
|
187
|
+
class << self
|
188
|
+
abstract :say
|
189
|
+
end
|
185
190
|
end
|
186
191
|
|
192
|
+
class Child < AbstractChild; end
|
193
|
+
|
187
194
|
Child.greet # => greet is abstract method defined in
|
188
195
|
# #<Class:AbstractParent>, and must implement.
|
189
196
|
# (NotImplementedError)
|
190
197
|
```
|
198
|
+
##### Get defined abstract methods in singleton class
|
199
|
+
*abstract_singleton_methods* Returns an array containing the names of abstract methods
|
200
|
+
in the receivers singleton class.
|
201
|
+
if set *true* to args include ancestor singleton classes abstract methods (default *true*).
|
202
|
+
```ruby
|
203
|
+
Child.abstract_singleton_methods # => [:say, :greet]
|
204
|
+
Child.abstract_singleton_methods(false) # => []
|
205
|
+
AbstractChild.abstract_singleton_methods # => [:say, :greet]
|
206
|
+
AbstractChild.abstract_singleton_methods(false) # => [:say]
|
207
|
+
```
|
191
208
|
### Do explicitly validation
|
192
209
|
if call *validate_not_implemented_abstract_methods* then can do explicitly validation.
|
193
210
|
```ruby
|
data/lib/abstractable.rb
CHANGED
@@ -43,9 +43,17 @@ module Abstractable
|
|
43
43
|
# (default true)
|
44
44
|
#
|
45
45
|
def abstract_methods(all = true)
|
46
|
-
|
47
|
-
|
48
|
-
|
46
|
+
do_abstract_methods(all, self, (ancestors - [self]))
|
47
|
+
end
|
48
|
+
|
49
|
+
# abstract_singleton_methods(all=true) -> array
|
50
|
+
#
|
51
|
+
# Returns an array containing the names of abstract methods in the receivers singleton class.
|
52
|
+
# if set true to args include ancestor singleton classes abstract methods.
|
53
|
+
# (default true)
|
54
|
+
#
|
55
|
+
def abstract_singleton_methods(all = true)
|
56
|
+
do_abstract_methods(all, singleton_class, (ancestors - [self]).map(&:singleton_class))
|
49
57
|
end
|
50
58
|
|
51
59
|
# Unimplemented abstract methods validation.
|
@@ -83,6 +91,18 @@ module Abstractable
|
|
83
91
|
@individual_abstract_methods ||= []
|
84
92
|
end
|
85
93
|
|
94
|
+
def do_abstract_methods(all = true, klass, ancestors_of_klass)
|
95
|
+
result = []
|
96
|
+
individual_abstract_methods_reader = lambda { |clazz| clazz.class_eval { individual_abstract_methods } }
|
97
|
+
if klass.is_a? Abstractable
|
98
|
+
result.push(*individual_abstract_methods_reader.call(klass))
|
99
|
+
return result unless all
|
100
|
+
end
|
101
|
+
ancestors_of_klass.each_with_object(result) do |ancestor, array|
|
102
|
+
array.push(*individual_abstract_methods_reader.call(ancestor)) if ancestor.is_a? Abstractable
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
86
106
|
def validate_on_create(create_method_name)
|
87
107
|
validate_not_implemented_abstract_methods if required_validate?
|
88
108
|
if is_a?(Abstractable) && 0 < abstract_methods(false).size
|
data/lib/abstractable/version.rb
CHANGED
data/spec/abstractable_spec.rb
CHANGED
@@ -241,10 +241,18 @@ describe Abstractable, "Class method" do
|
|
241
241
|
end
|
242
242
|
end
|
243
243
|
|
244
|
-
class
|
244
|
+
class AbstractSubApplication < AbstractApplication
|
245
|
+
class << self
|
246
|
+
abstract :version, :help
|
247
|
+
end
|
248
|
+
end
|
245
249
|
|
246
|
-
class
|
250
|
+
class NotImplApplication < AbstractSubApplication; end
|
251
|
+
|
252
|
+
class Application < AbstractSubApplication
|
247
253
|
def self.name; end
|
254
|
+
def self.version; end
|
255
|
+
def self.help; end
|
248
256
|
end
|
249
257
|
|
250
258
|
end
|
@@ -261,11 +269,20 @@ describe Abstractable, "Class method" do
|
|
261
269
|
end
|
262
270
|
|
263
271
|
it "find not implemented info from singleton class" do
|
264
|
-
h = {AbstractApplication.singleton_class => [:name]
|
272
|
+
h = {AbstractApplication.singleton_class => [:name],
|
273
|
+
AbstractSubApplication.singleton_class => [:version, :help]
|
274
|
+
}
|
265
275
|
expect(Abstractable.find_not_implemented_info_from_singleton(NotImplApplication)).to eq(h)
|
266
276
|
expect(Abstractable.find_not_implemented_info_from_singleton(Application)).to eq({})
|
267
277
|
end
|
268
278
|
|
279
|
+
it "get abstract methods of singleton class" do
|
280
|
+
AbstractApplication.extend Abstractable
|
281
|
+
expect(AbstractApplication.abstract_singleton_methods).to eq([:name])
|
282
|
+
expect(AbstractSubApplication.abstract_singleton_methods).to eq([:version, :help, :name])
|
283
|
+
expect(AbstractSubApplication.abstract_singleton_methods(false)).to eq([:version, :help])
|
284
|
+
end
|
285
|
+
|
269
286
|
end
|
270
287
|
|
271
288
|
describe Abstractable, "Use environment variable: ABSTRACTABLE_IGNORE_VALIDATE" do
|