Private constants in Ruby

Public constants

constants in Ruby are always visible by default. An example:

# person.rb
class Person
  ADULT_AGE = 18
end

and the value access:

Person::ADULT_AGE # => 18

However it is very often not necessary to exhibit the constants as public (for instance as a result of Replacing Magic Numbers). They should be removed from the public API, whenever they are only required within the class itself.

Private constants

To make a constant externally invisible, It is not appropriate to declare the constant to be private:

# person.rb
class Person
  private
  ADULT_AGE = 18
end

because it is still accessible:

Person::ADULT_AGE # => 18

Since Ruby 1.9.3 constants can be made private with Module#private_constant explicitly:

# person.rb
class Person
  ADULT_AGE = 18
  private_constant :ADULT_AGE

  def initialize age
    @age = age
  end

  def adult?
    @age >= ADULT_AGE
  end
end

Indeed then it is not public anymore and trying to access it, raises a NameError:

Person::ADULT_AGE
# => NameError: private constant Person::ADULT_AGE referenced

Though they are still accessible inside the class. The boolean method adult? takes advantage from the private constant:

Person.new(18).adult? # => true

Listing public and private constants

In the following example there are two constants: RETIREMENT_AGE is public and ADULT_AGE is private:

# person.rb
class Person
  RETIREMENT_AGE = 68
  ADULT_AGE      = 18
  private_constant :ADULT_AGE
end

All public constants of a class can be listed with constants like:

Person.constants # => [:RETIREMENT_AGE]

The same method, but with the parameter false returns all constants (public and private):

Person.constants false # => [:RETIREMENT_AGE, :ADULT_AGE]

Accordingly getting all private constants:

Person.constants(false) - Person.constants # => [:ADULT_AGE]