这个双冒号::是什么?例如Foo:酒吧。

我找到了一个定义:

::是一个一元操作符,允许在类或模块内定义的:常量、实例方法和类方法从类或模块外的任何地方访问。

如果你只能使用::来暴露任何东西,那么作用域(私有的,受保护的)有什么用呢?


当前回答

加上前面的答案,使用::访问实例方法是有效的Ruby。以下均有效:

MyClass::new::instance_method
MyClass::new.instance_method
MyClass.new::instance_method
MyClass.new.instance_method

根据最佳实践,我认为只推荐最后一种。

其他回答

这一切都是为了防止定义与链接到项目中的其他代码冲突。这意味着你可以把事情分开。

例如,你可以在你的代码中有一个名为“run”的方法,你仍然可以调用你的方法,而不是在你链接的其他库中定义的“run”方法。

不,它不是访问每个方法,它是一个“解析”操作符,也就是说,你用它来解析一个常量/静态符号的范围(或者你可以说的位置)。

例如,在第一行中,Rails使用它来查找ActiveRecord内部的基类。模块,在你的第二个模块中,它用于定位路由类的类方法(静态),等等。

它不是用来暴露任何东西,而是用来“定位”你瞄准镜周围的东西。

http://en.wikipedia.org/wiki/Scope_resolution_operator

Surprisingly, all 10 answers here say the same thing. The '::' is a namespace resolution operator, and yes it is true. But there is one gotcha that you have to realize about the namespace resolution operator when it comes to the constant lookup algorithm. As Matz delineates in his book, 'The Ruby Programming Language', constant lookup has multiple steps. First, it searches a constant in the lexical scope where the constant is referenced. If it does not find the constant within the lexical scope, it then searches the inheritance hierarchy. Because of this constant lookup algorithm, below we get the expected results:

module A
  module B
      PI = 3.14
      module C
        class E
          PI = 3.15
        end
        class F < E
          def get_pi
            puts PI
          end
        end
      end
  end
end
f = A::B::C::F.new
f.get_pi
> 3.14

F继承自E,而B模块在F的词法范围内。因此,F实例将引用模块B中定义的常数PI。现在,如果模块B没有定义PI,那么F实例将引用超类E中定义的PI常量。

但是如果我们使用'::'而不是嵌套模块呢?我们会得到同样的结果吗?不!

通过在定义嵌套模块时使用名称空间解析操作符,嵌套模块和类不再在其外部模块的词法范围内。如下所示,在A::B中定义的PI不在A::B::C::D的词法范围内,因此当我们试图在get_pi实例方法中引用PI时,会得到未初始化的常量:

module A
end

module A::B
  PI = 3.14
end

module A::B::C
  class D
    def get_pi
      puts PI
    end
  end
end
d = A::B::C::D.new
d.get_pi
NameError: uninitialized constant A::B::C::D::PI
Did you mean?  A::B::PI

::允许您访问在另一个类或模块中定义的常量、模块或类。它用于提供名称空间,以便不同作者的方法名和类名不会与其他类冲突。

当你在Rails中看到ActiveRecord::Base时,这意味着Rails有类似于

module ActiveRecord
  class Base
  end
end

例如,在ActiveRecord模块中一个名为Base的类,然后被引用为ActiveRecord::Base(你可以在Rails源代码ActiveRecord -n.n.n/lib/active_record/ Base .rb中找到这个)

::的常用用法是访问模块中定义的常量。

module Math
  PI = 3.141 # ...
end

puts Math::PI

操作符不允许绕过标记为private或protected的方法的可见性。

module Amimal
      module Herbivorous
            EATER="plants" 
      end
end

Amimal::Herbivorous::EATER => "plants"

::用于创建作用域。为了从2个模块中访问Constant EATER,我们需要确定模块的范围以达到常数