Module: TypeToolkit::HasAbstractMethods
- Defined in:
- lib/type_toolkit/has_abstract_methods.rb
Overview
Given a class Foo, abstract methods can be defined at two levels:
- Instance methods available on the instance of Foo
- "Class methods" available on the Foo class itself
In case 1, the storage belongs one level up, in the class Foo.
In case 2, the storage belongs two levels up, in the singleton class of Foo (Foo::<Foo>)
Instance Method Summary collapse
-
#__register_abstract_method(method_name) ⇒ Object
Private API, do not use directly.
-
#abstract_instance_methods(include_super = true) ⇒ Object
Returns all methods that are abstract and have not been implemented.
-
#abstract_method?(method_name) ⇒ Boolean
Returns true if the given method is abstract, and has not been implemented.
-
#abstract_method_declared?(method_name) ⇒ Boolean
Returns true if the given method name was ever marked abstract, even if it has a concrete implementation.
-
#declared_abstract_instance_methods(include_super = true) ⇒ Object
Returns all methods that were marked abstract (even those which are implemented).
Instance Method Details
#__register_abstract_method(method_name) ⇒ Object
Private API, do not use directly. Only meant to be called from the abstract macro.
14 15 16 17 18 |
# File 'lib/type_toolkit/has_abstract_methods.rb', line 14 def __register_abstract_method(method_name) # :nodoc: ( @__abstract_methods ||= Set.new #: Set[Symbol]? ) << method_name end |
#abstract_instance_methods(include_super = true) ⇒ Object
Returns all methods that are abstract and have not been implemented.
54 55 56 57 58 59 60 |
# File 'lib/type_toolkit/has_abstract_methods.rb', line 54 def abstract_instance_methods(include_super = true) #: self as HasAbstractMethods & Module[top] declared_abstract_instance_methods(include_super).reject do |m| method_defined?(m) || private_method_defined?(m) end end |
#abstract_method?(method_name) ⇒ Boolean
Returns true if the given method is abstract, and has not been implemented.
Calling it will raise an AbstractMethodNotImplementedError.
Similar to public_method_defined? and friends, this method is called on a class to check if the method
is defined for instances of that class. For example:
if Foo.abstract_method?(:instance_method)
Foo.new.instance_method # Will raise AbstractMethodNotImplementedError
end
if Foo.singleton_class.abstract_method?(:class_method)
Foo.class_method # Will raise AbstractMethodNotImplementedError
end
99 100 101 102 103 104 105 106 |
# File 'lib/type_toolkit/has_abstract_methods.rb', line 99 def abstract_method?(method_name) #: self as (HasAbstractMethods & Module[top]) # If the method is defined, it has a concrete implementation, so it's not abstract. return false if method_defined?(method_name) || private_method_defined?(method_name) abstract_method_declared?(method_name) end |
#abstract_method_declared?(method_name) ⇒ Boolean
Returns true if the given method name was ever marked abstract, even if it has a concrete implementation.
Similar to public_method_defined? and friends, this method is called on a class to check if the method
is defined for instances of that class. For example:
if Foo.abstract_method_declared?(:instance_method)
Foo.new.instance_method # Might raise AbstractMethodNotImplementedError
end
if Foo.singleton_class.abstract_method_declared?(:class_method)
Foo.class_method # Might raise AbstractMethodNotImplementedError
end
76 77 78 79 80 81 82 |
# File 'lib/type_toolkit/has_abstract_methods.rb', line 76 def abstract_method_declared?(method_name) #: self as Module[top] @__abstract_methods&.include?(method_name) || included_modules.any? { |m| m.is_a?(HasAbstractMethods) && m.abstract_method_declared?(method_name) } || (defined?(super) && super) end |
#declared_abstract_instance_methods(include_super = true) ⇒ Object
Returns all methods that were marked abstract (even those which are implemented).
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/type_toolkit/has_abstract_methods.rb', line 22 def declared_abstract_instance_methods(include_super = true) #: self as HasAbstractMethods & Module[top] result = @__abstract_methods return result.to_a unless include_super if defined?(super) && (super_abstract_methods = super) if result result.merge(super_abstract_methods) else result = super_abstract_methods end end abstract_methods_in_interfaces = included_modules.flat_map do |m| m.is_a?(HasAbstractMethods) ? m.declared_abstract_instance_methods : [] end if abstract_methods_in_interfaces.any? if result&.any? result.merge(abstract_methods_in_interfaces) else result = abstract_methods_in_interfaces end end result.to_a end |