54

I am learning Ruby from the Poignant Guide to Ruby and in some of the code examples, I came across uses of the double colon and dot that seem to be used for the same purpose:

File::open( 'idea-' + idea_name + '.txt', 'w' ) do |f|
   f << idea
end

In the above code, the double colon is being used to access the open method of the File class. However, I later came across code that used a dot for the same purpose:

require 'wordlist'
# Print each idea out with the words fixed
Dir['idea-*.txt'].each do |file_name|
   idea = File.read( file_name )
   code_words.each do |real, code| 
     idea.gsub!( code, real )
   end
puts idea
end 

This time, a dot is being used to access the read method of the File class. What is the difference between:

File.read()

and

File::open()
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
flyingarmadillo
  • 2,131
  • 5
  • 21
  • 37
  • 36
    I really don't think this is a duplicate of that. Nowhere in that question or its answers is the use of `::` with regard to singleton methods discussed. – Andrew Marshall Jun 15 '12 at 02:49
  • 9
    I agree. I saw that other question before I opened this one. However, the answer to my question was not explicitly given. The other question discusses the use only of the :: operator. Maybe its hints at the use use of the dot operator in a subtle way, but when you are new to something, you need the answer in a very distinct form. And like I stated, I am new to ruby. – flyingarmadillo Jun 15 '12 at 04:30
  • 1
    The duplicates offered by the moderator are not helpful. However there is a good answer here: https://stackoverflow.com/questions/43134/is-there-a-difference-between-and-when-calling-class-methods-in-ruby – inopinatus Jun 14 '19 at 02:24

1 Answers1

34

It's the scope resolution operator.

An example from Wikipedia:

module Example
  Version = 1.0

  class << self # We are accessing the module's singleton class
    def hello(who = "world")
       "Hello #{who}"
    end
  end
end #/Example

Example::hello # => "Hello world"
Example.hello "hacker" # => "Hello hacker"

Example::Version # => 1.0
Example.Version # NoMethodError

# This illustrates the difference between the message (.) operator and the scope
# operator in Ruby (::).
# We can use both ::hello and .hello, because hello is a part of Example's scope
# and because Example responds to the message hello.
#
# We can't do the same with ::Version and .Version, because Version is within the
# scope of Example, but Example can't respond to the message Version, since there
# is no method to respond with.
alex
  • 479,566
  • 201
  • 878
  • 984
  • 25
    This does not answer the question: "what is the difference between `File.read()` and `File::open()`?". And why can both be used to call a method? When would we choose one over the other? – antinome Oct 06 '14 at 14:49
  • 38
    There is NO difference between :: and . when calling class (static) methods in functionality. But you can use :: to access constants and other namespaced things, for which you can't use dot. I personally use dot all the time, but my colleague use :: for calling static methods. Maybe it is somewhat aesthetically nicer when you call namespaced thing, like Foo::Bar::open (instead of Foo::Bar.open), but it works the same both ways. Performance is the same too. P.S. Here is nice discussion on this topic: https://www.ruby-forum.com/topic/107527 – Dalibor Filus May 18 '15 at 09:07
  • 1
    This example lacks a version: `Example::hello("hacker")` I feel like the example given implies this is not possible, though the text states it is. – supermitch Dec 06 '19 at 02:03