How to create private class methods in Ruby

There are a few different ways to create private class methods in the Ruby programming language.

First let's see how we can create a class method in Ruby:

class BlogPost
  attr_accessor :title, :description
  
  def initialize(title, description)
    @title = title
    @description = description
    class.add_post(self)
  end
  
  @@posts = []
  def self.posts
    @@posts
  end
  
  def self.add_post(post)
    @@posts << post
  end
end

As you will see, we have two class methods here, posts and add_post. Both of them are public class methods. When a new instance of BlogPost is created, the instance is added to the posts list using the add_post method.

With the above code, there is nothing stopping someone from calling BlogPost.add_post({ hello: 'world' }) or BlogPost.add_post(123) from any other place in the program.

Using private_class_method to declare a class method as private

To prevent that from happening, we can make the add_post class method private by using private_class_method.

Here's how that would look:

class BlogPost
  # ...
  
  def self.add_post(post)
    @@posts << post
  end
  private_class_method :add_post
end

An alternate way of declaring a class method as private is this:

class BlogPost
  # ...
  
  private_class_method def self.add_post(post)
    @@posts << post
  end
end

You can see that private_class_method can be used with a symbol argument, :add_post, which is the name of the class method, or it can be passed the result of the class method definition def self.add_post.

Using private in class << self (eigenclass) to make a class method private

The other way of declaring a class method as private is to use the eigenclass of your Ruby class.

Let's look at the above example with add_post class method in the BlogPost class written with the eigenclass notation:

class BlogPost
  # ...
  class << self
    def add_post(post)
      @@posts << post
    end
  end
end

You can declare that class method private by using the private method:

class BlogPost
  # ...
  class << self
    def add_post(post)
      @@posts << post
    end
    private :add_post
  end
end

This is similar to how you would declare instance methods as private.


Hope you enjoyed this article!