Carlos Medeiros

I'm Programmer for Ruby & Rails

How to Make Ruby Constants Private

06 Jan 2020 » general

Straight to the Point


In order to make your Ruby constants not accessible to the outside world, Ruby gives us the private_constant method.

class Phrase
  RE = REGULAR_EXPRESSION = { words: /\b[\w']+\b/ }.freeze
  private_constant :RE, :REGULAR_EXPRESSION

  private

  attr_reader :phrase

  def initialize(phrase)
    @phrase = phrase.downcase
  end

  def words
    phrase.scan(RE[:words])
  end

  public

  def word_count
    words.tally
  end
end


Why

One main concern in OOP design is the balance between what to make accessible in a class’s public interface and what to not. By default, Ruby makes all constants accessible to the outside world, and you can check the available constants by using the #constants method.

irb(main): 001:0> Math.constants
=> [:DomainError, :PI, :E]


Wrapping information inside a constant can improve readability and reusability. For instance, if we just used the value 2.7182... we may not notice that it stands for the Euler’s number. However if Math::E is called, then chances are that the value is going to make sense.

In the first code snipped, a constant was used to hold the regexp value. Creating a regexp dictionary is a common practice to improve the it’s readability. So now instead of using phrase.scan(/\b[\w']+\b/) and probably wouldn’t easily remember, I can just use `phrase.scan(RE[:words]) and know that I am scanning for words.

Now, when we hit ClassName.constants our private constants won’t show up and it is going to only be accessible to our private interface.