在Ruby中的其他模块中包含模块意味着什么?

时间:2013-07-12 21:57:32

标签: ruby

module Fabrication
  module Syntax

    # Extends Fabrication to provide make/make! class methods, which are
    # shortcuts for Fabricate.build/Fabricate.
    #
    # Usage:
    #
    # require 'fabrication/syntax/make'
    #
    # User.make(:name => 'Johnny')
    #
    #
    module Make
      def make(*args, &block)
        overrides = Fabrication::Support.extract_options!(args)
        klass = name.underscore.to_sym
        fabricator_name = args.first.is_a?(Symbol) ? "#{klass}_#{args.first}" : klass
        Fabricate.build(fabricator_name, overrides, &block)
      end

      def make!(*args, &block)
        overrides = Fabrication::Support.extract_options!(args)
        klass = name.underscore.to_sym
        fabricator_name = args.first.is_a?(Symbol) ? "#{klass}_#{args.first}" : klass
        Fabricate(fabricator_name, overrides, &block)
      end
    end
  end
end

Object.extend Fabrication::Syntax::Make

3 个答案:

答案 0 :(得分:0)

它本质上是命名空间。你可以用module Fabrication::Syntax::Make做同样的事情。无论出于何种原因,嵌套它们是最知名的宝石/项目所做的事情,而且由于这个未知的原因我也会这样做。我希望能够深入了解为什么人们通常更喜欢使用更直接的方法进行嵌套。

答案 1 :(得分:0)

就在你最后一行。如果您在其他module内定义module,则它将被命名空间。因此,使用您的代码Make模块可以从外部Fabrication模块定义访问其命名空间:

Fabrication::Syntax::Make

这允许您在根命名空间中定义模块Make而不会发生命名冲突。

答案 2 :(得分:0)

命名空间。您可以使用::运算符深入嵌套命名空间。

检查出来:

module Galaxy
  module StarSystem
    module Planet
    end

    Galaxy     # references Galaxy
    StarSystem # references Galaxy::StarSystem
    Planet     # references Galaxy::StarSystem::Planet

  end
end

Galaxy                     # references the Galaxy module
Galaxy::StarSystem::Planet # References the Planet module declared above.
Planet                     # Exception! No constant Planet exists in this namespace

正如您所看到的,这允许您以保持模块化的方式构建代码。您可以编写一个使用man不同类和模块的组件,但它们都位于单个命名空间下。从该代码中,您可以轻松访问在其自己的命名空间或父命名空间中声明的任何常量。但是除非你明确地深入研究它们,否则其他代码无法看到这些常量。

结果是组织良好且结构化的组件,可以很容易地与其他组件混合,因为它们完全存在于一个名称中,不会与项目中的其他代码冲突。