Пока я знаю, что для получения дочернего модуля нужно выполнить такую операцию:

module ParentModule
  module Foo
    # to be implemented
    def self.get_bar
      ::ParentModule::Bar
    end
  end

  module Bar
    # to be implemented
  end
end

Однако есть ли способ получить родственный модуль без ссылки на родительский? Что-то вроде этого:

module Foo
  def self.get_bar
    ::Bar # doesn't work actually
  end
end
1
DreamWalker 28 Дек 2015 в 23:29

2 ответа

Лучший ответ

Это проще, чем вы думали

module ParentModule
  module Foo
    def self.get_bar
      Bar
    end
  end
end

::, с которым вы пробовали, дает ruby указание найти это имя в области верхнего уровня. Если вы его опустите, ruby сначала будет искать в текущей области видимости, затем в своей родительской, затем в родительской и вплоть до верхнего уровня.

Итак, ParentModule::Foo::Bar не будет найден, а ParentModule::Bar будет.

2
Sergio Tulentsev 29 Дек 2015 в 07:57
mod = ParentModule::Bar
  #=> "ParentModule::"
parent_str = mod.to_s[/.+::/]
  #=> "ParentModule::" 
kids = ObjectSpace.each_object(Module).select { |m| m.to_s =~ /^#{parent_str}/ }
  #=> [ParentModule::Bar, ParentModule::Foo] 

Итак, братья и сестры mod:

kids - [mod]
  #=> [ParentModule::Foo]
1
Cary Swoveland 29 Дек 2015 в 07:01