@@ -23,27 +23,18 @@ def __register_abstract_method(method_name) # :nodoc:
2323 def abstract_instance_methods ( include_super = true )
2424 #: self as Module[HasAbstractMethods]
2525
26- result = @__abstract_methods
26+ result = @__abstract_methods #: Set[Symbol]?
2727
28- return result . to_a unless include_super
29-
30- if defined? ( super ) && ( super_abstract_methods = super )
31- if result
32- result . merge ( super_abstract_methods )
33- else
34- result = super_abstract_methods
35- end
36- end
37-
38- abstract_methods_in_interfaces = included_modules . flat_map do |m |
39- m . is_a? ( HasAbstractMethods ) ? m . abstract_instance_methods : [ ]
40- end
41-
42- if abstract_methods_in_interfaces . any?
43- if result &.any?
44- result . merge ( abstract_methods_in_interfaces )
45- else
46- result = abstract_methods_in_interfaces
28+ if include_super
29+ ancestors . each do |m |
30+ methods = m . instance_variable_get ( :@__abstract_methods )
31+ if methods &.any?
32+ if result
33+ result . merge ( methods )
34+ else
35+ result = methods
36+ end
37+ end
4738 end
4839 end
4940
@@ -67,9 +58,14 @@ def abstract_instance_methods(include_super = true)
6758 def abstract_method_declared? ( method_name )
6859 #: self as Module[top]
6960
70- @__abstract_methods &.include? ( method_name ) ||
71- included_modules . any? { |m | m . is_a? ( HasAbstractMethods ) && m . abstract_method_declared? ( method_name ) } ||
72- ( defined? ( super ) && super )
61+ # FIXME: Allocating the `ancestors` array is not great.
62+ # I tried a recursive approach, but that didn't quite work.
63+ # There is only one implementation of `abstract_method_declared?` in the ancestor chain, so there is no `super` to call.
64+ # This method always checked the ivar of the current class, which might not be set. What we actually want is to
65+ # walk up the ancestor chain, and check the ivar of each ancestor.
66+ ancestors . any? do |m |
67+ m . instance_variable_get ( :@__abstract_methods ) &.include? ( method_name )
68+ end
7369 end
7470
7571 # Returns true if the given method is abstract, and has not been implemented.
0 commit comments