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?
::
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.