Я получал переполнение стека, когда пытался Reactormonk ответить на большие библиотеки, такие как RSpec.
Вот решение, которое должно отфильтровывать циклические ссылки и внешние ссылки, проверяя, действительно ли «потомки» являются потомками родительского модуля, через который мы перебираем:
def parent_of(mod)
parent_name = mod.name =~ /::[^:]+\Z/ ? $`.freeze : nil
Object.const_get(parent_name) if parent_name
end
def all_modules(mod)
[mod] + mod.constants.map { |c| mod.const_get(c) }
.select {|c| c.is_a?(Module) && parent_of(c) == mod }
.flat_map {|m| all_modules(m) }
end
(Метод parent_of()
адаптирован из модуля # parent ActiveSupport, который, похоже, не работает надежно для библиотечных классов.)
* * 1010