Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between these Ruby namespace conventions?

Tags:

ruby

So Module can be used in Ruby to provide namespacing in addition to mixins, as so:

module SomeNamespace   class Animal    end end  animal = SomeNamespace::Animal.new 

But I've also seen the following used:

module SomeNamespace end  class SomeNamespace::Animal  end  animal = SomeNamespace::Animal.new 

My question is how they're different (if they are) and which is more idiomatic Ruby?

like image 295
Martin Avatar asked Oct 19 '11 12:10

Martin


People also ask

What are namespaces in Ruby?

Namespace in Ruby allows multiple structures to be written using hierarchical manner. Thus, one can reuse the names within the single main namespace. The namespace in Ruby is defined by prefixing the keyword module in front of the namespace name. The name of namespaces and classes always start from a capital letter.

What is difference between module and class in Ruby?

What is the difference between a class and a module? Modules are collections of methods and constants. They cannot generate instances. Classes may generate instances (objects), and have per-instance state (instance variables).

Can you instantiate a module in Ruby?

You can define and access instance variables within a module's instance methods, but you can't actually instantiate a module.

What are Ruby modules explain in detail?

Ruby module is a collection of methods and constants. A module method may be instance method or module method. Instance methods are methods in a class when module is included. Module methods may be called without creating an encapsulating object while instance methods may not.


2 Answers

The difference lies in nesting.

In the example below, you can see that the former method using class Foo, can get the outer scope's constant variables BAR_A without errors.

Meanwhile, class Baz will bomb with an error of uninitialized constant A::B::Baz::BAR_A. As it doesn't bring in A::* implicitly, only A::B::*explicitly.

module A   BAR_A = 'Bar A!'   module B     BAR_B = 'Bar B!'       class Foo         p BAR_A         p BAR_B       end   end end  class A::B::Baz   p BAR_A   p BAR_B end 

Both behaviors have their place. There's no real consensus in the community in my opinion as to which is the One True Ruby Way (tm). I personally use the former, most of the time.

like image 186
peakxu Avatar answered Oct 06 '22 01:10

peakxu


The only difference between the two approaches is that the second one will throw uninitialized constant Object::SomeNamespace if the namespace hasn't previously been declared.

When declared in a single file, I would opt for the first one because you don't have to repeat SomeNamespace.

When using multiple files I also use the second one, to avoid running into the following problem:

# in a.rb require 'b'  module SomeNamespace   def self.animal     Animal.new   end end  # in b.rb class SomeNamespace::Animal  end  # irb require 'a' # explodes with the uninitialized constant error 

This example may be contrived, but it's easy to trigger it if your code base is a little bit bigger. I usually use the explicit way (your first one) to avoid this.

One thing that may be helpful when using the second form is that it will detect typos in the namespace.

There doesn't seem to be an established way to create namespaces, Devise for example mixes both approaches: first one, second one.

like image 28
Benoit Garret Avatar answered Oct 05 '22 23:10

Benoit Garret