Search code examples
rubyoop

What's the benefit of having a scope-resolution operator within the language?


For example: puts FileManagement::CSV.Reader.new

Why not: puts FileManagement.CSV.Reader.new?

Why this differentiation? What's the benefit of having the additional ::-operator?


Solution

  • :: is for namespaces and . is for designating a receiver in a method call.

    If you have both, a constant and a class method with the same name within the same namespace, e.g.:

    module Foo
      Bar = 123
    
      def self.Bar
        456
      end
    end
    

    then the scope resolution operator resolves to the constant whereas the dot resolves to the class method:

    Foo::Bar
    #=> 123
    
    Foo.Bar
    #=> 456
    

    This is also true if the constant refers to another class or module which was defined under Foo.

    If you only had Foo.Bar there’d be no way to get the Bar constant.

    In addition, you can target the top-level namespace by using the scope resolution operator as a prefix:

    Bar = 123
    
    module Foo
      Bar = 456
    
      def self.bars
        [::Bar, Bar]
      end
    end
    
    Foo.bars
    #=> [123, 456]
    

    In the above, .Bar would raise a SyntaxError.

    Finally, :: can be used to define constants within a namespace:

    module Foo
    end
    
    module Foo::Bar
    end
    
    Foo::Bar::Baz = 123
    

    module Foo.Bar or Foo.Bar.Baz = 123 both wouldn't work.