8

I am looking at the Rails Engine tutorial and one of the code blocks looks like the following:

module Blorgh
  class Engine < ::Rails::Engine
    isolate_namespace Blorgh
  end
end

What does the ::Rails::Engine mean? I know this is probably a trivial Ruby question, however, I don't seem to be able to find anything anywhere.

Thanks.

El Guapo
  • 5,581
  • 7
  • 54
  • 82
  • 1
    symbolhound.com is good for this sort of thing. – mu is too short Feb 25 '16 at 03:42
  • @muistooshort I fail to see how this question is a duplicate of what you marked as the existing article. – Chris Peters Feb 25 '16 at 04:06
  • @ChrisPeters `::` at the beginning means the same thing as it does elsewhere, the answers even cover the leading `::` case. Disagree if you want or go searching for a better duplicate. – mu is too short Feb 25 '16 at 04:26
  • @muistooshort I think it is valid to re-open this question, because he is specifically asking what it means in front of a symbol – Tilo Feb 25 '16 at 04:47
  • 1
    I also think it's valid to re-open the question. The linked answer 'sort of' answers the question, but not directly enough to guide the OP. `::` **in front of** a constant refers back to the host app. For instance, in an engine, `class FooController < ::ApplicationController` mean **inherit from the `ApplicationController` in the host app**. But, the referenced question doesn't make that super clear. A clearer answer would be valuable. – jvillian Feb 25 '16 at 05:42
  • Yeah, alright, maybe I jumped the gun. – mu is too short Feb 25 '16 at 06:03
  • Looks like the correct duplicate was found. @muistooshort Thank you for everything you've done for the SO community though. We all jump the gun from time to time. :) – Chris Peters Feb 25 '16 at 14:46

3 Answers3

12

So, Ray has this exactly right. I would just like to add a further example.

Let's say we have an engine called Foo (original, right?) that is mounted in a host application called Bar with something like:

#bar/config/routes.rb
Rails.application.routes.draw do
  ...
  mount Foo::Engine, at: '/'
  ...
end

Foo has an application_controller:

#foo/app/controllers/foo/application_controller.rb
module Foo
  class ApplicationController < ActionController::Base
    ...
    def foo_action
      ...
    end
    ...
  end
end

And Bar has an application_controller:

#bar/app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  ...
  def bar_action
    ...
  end
  ...
end

Now, let's say we have two controllers within the Foo engine, like:

#foo/app/controllers/foo/baz_controller.rb
module Foo
  def BazController < ApplicationController
    ...
  end
end

and

#foo/app/controllers/foo/bif_controller.rb
module Foo
  def BifController < ::ApplicationController
    ...
  end
end

The BazController inherits from ApplicationController (no :: in front). This means that it looks up ApplicationController in the current namespace (Foo). And so it will have the foo_action defined in Foo::ApplicationController.

The BifController inherits from ::ApplicationController (:: in front). This means that it looks up ApplicationController in the global namespace which, in this case, is the host application Bar. And so it will have the bar_action defined in Bar's ApplicationController.

jvillian
  • 19,953
  • 5
  • 31
  • 44
5

Think of all the Modules and Classes hierarchically: it is looking for "Rails" at the top-level with "Engine" at the next level.

e.g.:

  module Rails
    class Engine
    end
  end

  module SomethingElse
    class Rails
    end
  end

::Rails selects the Module in the first code snippet, which is on the top-level.

::Rails::Engine selects the Class Engine which is in the top-level Rails Module.

Tilo
  • 33,354
  • 5
  • 79
  • 106
5

The :: at the front of ::Rails::Engine means to lookup Rails::Engine at the top of the global namespace, not inside the Blorgh namespace.

Without contrast, without the :: as in this code,

module Blorgh
  class Engine < Rails::Engine
    isolate_namespace Blorgh
  end
end

the second line would be looking for Blorgh::Rails and you would get an error, NameError: uninitialized constant Blorgh::Rails.

Ray Baxter
  • 3,181
  • 23
  • 27