Search code examples
ruby-on-railsrubypostgresqlpg

Namespacing module method definition


I accidentally came across this piece of code in Ruby's Postgresql gem:

### Convenience alias for PG::Connection.new.
def self::connect( *args )
  return PG::Connection.new( *args )
end

I played around a bit and turns out that this thing is used just like a normal module class method (it's called like this: PG.connect). In fact we could instead say def self.connect ( #args ) ... end and it would work just the same.

Since self::whatever is a first for me I'm wondering what exactly does self namespaces in such a context and what is its true purpose in this case. Can anyone help shed some light on this?


Solution

  • :: is the scope resolution operator. So self::connect resolves connect from self. Which means that its equivalent to self.connect. You can see how it works from this very contrived example:

    class Foo; end
    
    class Bar
      def Foo::baz
        "Hello World"
      end
    end
    
    puts Foo.baz # "Hello World"
    

    Of course we could also just use def Foo.baz to get the exact same result.

    Using double colons for method definition is discouraged by the Ruby Style guide:

    Do not use :: to define class methods.

    # bad
    class Foo
      def self::some_method
      end
    end
    
    # good
    class Foo
      def self.some_method
      end
    end
    

    Its also not recommended for anything other than referencing constants and constructors:

    Use :: only to reference constants (this includes classes and modules) and constructors (like Array() or Nokogiri::HTML()). Do not use :: for regular method invocation.