Is there any difference between
module Foo class Engine < Rails::Engine end end and
module Foo class Engine < ::Rails::Engine end end Constants in Ruby are nested like files and directories in filesystem. So, constants are uniquely identified by their paths.
To draw an analogy with the file system:
::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. Here is the illustration of possible error:
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 Module Foo, it may interpret it as Foo::Rails::Engine. I've seen errors like this at times and had to add the additional :: in front of an include.Rails::Engine is defined outside of Foo and it is also not defined inside Foo then Foo::Engine1.superclass will be Rails::Engine as desired.Rails::Engine #is a path relative to the current tree level. # like ./Rails/Engine in FS. This is not quite true!
Let's have an example:
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 So when you say M::Y ruby looks up for the closest defintion no matter if it is inside the current scope or outer scope or outer outer scope etc.