模块如何解决常数的范围?

时间:2013-12-30 21:48:49

标签: ruby module scope

我一直在读这本Ruby书,然后就是这个我不太了解的例子:

CONST = "outer"
module Mod
    CONST = 1
    def Mod.method1
        # module method
        CONST + 1
    end
end
module Mod::Inner
    def (Mod::Inner).method2
        CONST + " scope"
    end
end
Mod::CONST  # => 1
Mod.method1 # => 2
Mod::Inner::method2 # => "outer scope"

请您向我解释一下(详细说明),以便我完全理解该范围如何在Ruby中运行。 谢谢。

2 个答案:

答案 0 :(得分:2)

Ruby中的常量(以大写字母开头的标识符)可以根据定义/访问它们的词汇范围进行访问。

method1中,CONST范围内的Mod优先于最外层CONST。在method2中,CONST范围内的Mod在词汇上不可见,因此访问了最外面的CONST

对于方法定义本身,当使用前面的模块常量(例如ModMod::Inner)限定名称时,该方法被定义为“模块方法”而不是实例方法self.class(默认值)。

模块/方法层次结构中的名称由::分隔,或者在模块和模块方法之间的分隔符的情况下,.

更新:请注意,Mod的{​​{1}}常量不可见的原因是method2未单独“打开”。该定义直接跳至Mod。如果代码更改为:

Mod::Inner

然后module Mod module Inner def (Mod::Inner).method2 ... 可以访问Mod的常量,并优先于外部范围内的任何常量。

答案 1 :(得分:2)

您会在Ruby常量查找here

上找到一个很好的解释

我会与代码片段分享一些解释:

CONST = "outer"
module Mod
  CONST = 1
  def Mod.method1
    # module method
    Module.nesting # => [Mod]
    CONST + 1
  end
end
module Mod::Inner
  def (Mod::Inner).method2
    Module.nesting # => [Mod::Inner]
    CONST + " scope"
  end
end


Mod::CONST  # => 1
Mod.method1 # => 2
Mod::Inner::method2 # => "outer scope"

查看Module.nesting(Mod::Inner).method2的评估Mod::InnerCONST的嵌套中查找,它在调用主对象之前找不到CONST的嵌套Mod::Inner.method2

在下面的示例中,您会看到CONST调用Mod :: Inner然后Mod调用它找到的CONST,因此无需调用{{ 1}}在对象

module Mod
  CONST = 1
  def Mod.method1
    Module.nesting # => [Mod]
    CONST + 1
  end

  module Inner
    def (Mod::Inner).method2
      Module.nesting # => [Mod::Inner, Mod]
      CONST.to_s + " scope"
    end
  end
end


Mod::CONST  # => 1
Mod.method1 # => 2
Object::CONST # => "outer"
Mod::Inner::method2 # => "1 scope"

如果有疑问,请使用嵌套的类/常量定义而不是词法,它总会按预期执行正确的操作