Ruby的双冒号(::)运算符使用差异

Cur*_*ind 29 ruby

两者之间有什么区别吗?

module Foo
  class Engine < Rails::Engine
  end
end
Run Code Online (Sandbox Code Playgroud)

module Foo
  class Engine < ::Rails::Engine
  end
end
Run Code Online (Sandbox Code Playgroud)

Fle*_*oid 52

Ruby中的常量嵌套在文件系统中的文件和目录中.因此,常量由它们的路径唯一标识.

与文件系统类比:

::Rails::Engine #is an absolute path to the constant.
# like /Rails/Engine in FS.

Rails::Engine #is a path relative to the current tree level.
# like ./Rails/Engine in FS.
Run Code Online (Sandbox Code Playgroud)

以下是可能的错误说明:

module Foo

  # We may not know about this in real big apps
  module Rails
    class Engine 
    end
  end

  class Engine1 < Rails::Engine
  end

  class Engine2 < ::Rails::Engine
  end
end

Foo::Engine1.superclass
 => Foo::Rails::Engine # not what we want

Foo::Engine2.superclass
 => Rails::Engine # correct
Run Code Online (Sandbox Code Playgroud)

  • 它取自Paolo Perrotta的"Metaprogramming Ruby"一书.非常有用的书,以加深Ruby的知识. (5认同)
  • 一个微妙的观点:如果`Rails :: Engine`是在`Foo`之外定义的,它也不是**在`Foo`中定义的那么``Foo :: Engine1.superclass`将是`Rails :: Engine` as期望. (3认同)

Vio*_*rel 5

Rails::Engine #is a path relative to the current tree level.
# like ./Rails/Engine in FS.
Run Code Online (Sandbox Code Playgroud)

这不是真的!

我们举个例子:

module M
  Y = 1
  class M
    Y = 2
    class M
      Y = 3
    end
    class C
      Y = 4
      puts M::Y
    end
  end
end

# => 3

module M
  Y = 1
  class M
    Y = 2
    class C
      Y = 4
      puts M::Y
    end
  end
end

# => 2

module M
  Y = 1
  class M
    Y = 2
    class M
      Y = 4
      puts M::Y
    end
  end
end

# => 4
Run Code Online (Sandbox Code Playgroud)

因此,当你说M :: Y ruby​​查找最接近的定义时,无论它是在当前范围内还是在外部范围内或外部外部范围内等.