Предположим, что мы имеем следующий модуль Foo
:
module Foo
class Bar
end
class Tar
end
module Goo
class Bar
end
end
end
Если вы не знаете, какие классы содержатся в Foo
, вы можете сделать следующее:
a = ObjectSpace.each_object(Class).with_object([]) { |k,a|
a << k if k.to_s.start_with?("Foo::") }
#=> [Foo::Tar, Foo::Goo::Bar, Foo::Bar]
См. ObjectSpace::each_object.
Затем вы можете сделать то, что хотите, с массивом a
. Может быть, вы хотите, чтобы сузить это clases, чьи имена заканчиваются "Bar"
:
b = a.select { |k| k.to_s.end_with?("Bar") }
#=> [Foo::Goo::Bar, Foo::Bar]
Если вы хотите, чтобы часть имен, исключает «Foo ::» (хотя я не могу себе представить, почему), это простая строка манипуляция:
b.map { |k| k.to_s["Foo::".size..-1] }
#=> ["Goo::Bar", "Bar"]
или
b.map { |k| k.to_s[/(?<=\AFoo::).*/]
#=> ["Goo::Bar", "Bar"] }
Обратите внимание, что нет объекта Bar
или Goo::Bar
.
_Sidenote_: ваше регулярное выражение будет производить неправильный результат на 'Foo :: Bar :: Baz' и любого класса, имеющих два и более уровня вложенности. – mudasobwa