如何访问父/兄弟模块方法

时间:2016-01-07 20:48:27

标签: ruby

有没有办法在baz_method内访问class Qux而没有先提到模块命名空间?当有许多嵌套模块时,代码看起来不干净。

module Foo
  module Bar
    module Baz
      class Qux
        def self.qux_method
          Foo::Bar::Baz.baz_method  
        end
      end
      def self.baz_method
      end
    end 
  end
end

3 个答案:

答案 0 :(得分:11)

首先在词法封闭模块中查找常量,然后在继承链中查找。

module Foo
  module Bar
    module Baz
      class Qux
        def self.qux_method
          Baz.baz_method    
        end
      end
      def self.baz_method
      end
    end
  end
end

这将有效,因为常量Baz将首先在词汇封闭模块(类)Qux中查找,但未找到它。查找在词法封闭模块Baz中继续,在那里也找不到它。因此,接下来将在词法封闭模块Bar中查找,其中 找到并且搜索停止。

注意:你写下你的标题:

  

Ruby,访问父/兄弟模块方法

这是错误的。这些模块既不是父母也不是兄弟姐妹。这里没有继承权。实际上,模块之间存在 no 关系。 常量和模块之间仅存在 关系:常量属于模块。

模块声明是词法嵌套的,但模块本身不是。

答案 1 :(得分:4)

您不需要指定整个命名空间链。你只需要消除歧义常数所需的数量。只需使用Baz.baz_method

module Foo
  module Bar
    module Baz
      class Qux
        def self.qux_method
          Baz.baz_method
        end
      end

      def self.baz_method
      end
    end
  end
end

答案 2 :(得分:2)

注意:除非您明确寻找相对模块访问权限,否则此元编程是不必要的。请改用@ drhining的solution

您可以使用Module#nesting动态爬升模块层次结构:

module Foo
  module Bar
    module Baz
      class Qux
        def self.qux_method
          Module.nesting[1].baz_method  
        end
      end

      def self.baz_method
        puts "foo!"
      end
    end
  end
end

在这种情况下,Module.nesting将提供以下内容(在qux_method中调用时):[Foo::Bar::Baz::Qux, Foo::Bar::Baz, Foo::Bar, Foo]

请注意,这是Baz的明确引用,而是对模块链中的任何一个级别的引用。