Skip to content

Commit

Permalink
Add extenders_of helper method
Browse files Browse the repository at this point in the history
This method is similar to `descendants_of`, but returns all modules
which extend the given module. That is, all modules (including classes),
whose singleton class (or parent thereof) includes the given module.
  • Loading branch information
sambostock committed Jan 29, 2024
1 parent 868d5e3 commit ef1eff5
Showing 1 changed file with 27 additions and 0 deletions.
27 changes: 27 additions & 0 deletions lib/tapioca/runtime/reflection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,33 @@ def descendants_of(klass)
T.unsafe(result)
end

# Returns an array with all modules which extend the supplied module
# (i.e. all modules whose singleton class, or ancestor thereof, includes the supplied module).
#
# module M; end
# extenders_of(M) # => []
#
# module E
# extend M
# end
# extenders_of(M) # => [E]
#
# class P
# extend M
# end
# extenders_of(M) # => [E, P]
#
# class C < P; end
# extenders_of(M) # => [E, P, C]
sig { params(mod: Module).returns(T::Array[Module]) }
def extenders_of(mod)
result = ObjectSpace.each_object(Module).select do |m|
T.cast(m, Module).singleton_class.included_modules.include?(mod)
end

T.cast(result, T::Array[Module])
end

# Examines the call stack to identify the closest location where a "require" is performed
# by searching for the label "<top (required)>". If none is found, it returns the location
# labeled "<main>", which is the original call site.
Expand Down

0 comments on commit ef1eff5

Please sign in to comment.