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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 72caaebf76f307c72dab808fd6301028497e8531
4
- data.tar.gz: d15d1ebfcd3920f10f5786c4b2082f02ec1e6ce6
3
+ metadata.gz: 438e87395388206c629f6329ecb65dd1e88f434f
4
+ data.tar.gz: c340f5981023a140b7f26558a7c5febf252bf878
5
5
  SHA512:
6
- metadata.gz: e988343385b4dfed7d9c4f5f46c7c3e4ee026bf88ddb69896816f597f360fe2c7f48aa8fd370e0ea0f1438c2c7a4b849292b0c9fc9461f2f7c1448c05be18fb1
7
- data.tar.gz: 71b245810a2b4694faca227546e2c488743fcdb6a0962daf4a5ec8b4db3e212078942154bd039309bc34a9bd589565ea87c8a64b0b9b3ce2e68683027cf25507
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 Child < AbstractParent
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
@@ -43,9 +43,17 @@ module Abstractable
43
43
  # (default true)
44
44
  #
45
45
  def abstract_methods(all = true)
46
- return individual_abstract_methods unless all
47
- collect = lambda { |klass, array| array.push(*klass.abstract_methods(false)) if klass.is_a? Abstractable }
48
- individual_abstract_methods + (ancestors - [self]).each_with_object([], &collect)
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
@@ -1,3 +1,3 @@
1
1
  module Abstractable
2
- VERSION = "1.0.2"
2
+ VERSION = "1.0.3"
3
3
  end
@@ -241,10 +241,18 @@ describe Abstractable, "Class method" do
241
241
  end
242
242
  end
243
243
 
244
- class NotImplApplication < AbstractApplication; end
244
+ class AbstractSubApplication < AbstractApplication
245
+ class << self
246
+ abstract :version, :help
247
+ end
248
+ end
245
249
 
246
- class Application < AbstractApplication
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: abstractable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenji Suzuki