Red Green Repeat Adventures of a Spec Driven Junkie

Making Class Methods Private in Ruby

This week, I learned that putting a class definition under the private block does not make it ‘private’ and there’s a few different ways of making a Ruby class method private! (Four to be exact!)

“Your class methods are not private!”

I learned about my class methods being public through RuboCop, when these kinds of errors started to appear:

myproject.rb:51:3: W: private (on line 50) does not make singleton methods private. Use private_class_method or private inside a class << self block instead.
  def self.foo
    ^^^

Oh, interesting. Why is that?

The best article I have found on the topic that explains it very well is: Private Class Methods, so go check it out for way more details. It’s very well written by Troy.

How to make private class methods in Ruby?

Like all things in Ruby, there are many ways of doing this.

  • class << self
  • private_class_method def self.method
  • private_class_method :method
  • private_class_method(...)

class << self; private block

Use the class << self block to arrange blocks of class methods similar to instance methods.

class MyClass
  class << self
    def public_class_method
      ...
    end

    private

    def private_class_method
      ...
    end
  end

  def public_instance_method
    ...
  end

  private

  def private_instance_method
    ...
  end
end

This is my preferred method as I like to have a ‘class methods’ section which mirrors the ‘instance methods’ section.

private_class_method def self.method

Make a single class method private on the method declaration line

private_class_method def self.private_class_method
  ...
end

This style would be perfect if there will be very few private class methods.

private_class_method :method

Make a bunch of class methods private through after their declaration:

def self.private_class_method
  ...
end

def self.private_class_method2
  ...
end

private_class_method :private_class_method, :private_class_method2

Note, this method only works with the symbol listings after the declaration. If the private_class_method line can be at the top of a file (or above the normal private line, that would more useful.

private_class_method(...)

Wrap only the private class methods in a block:

private_class_method(
  def self.private_class_method
    ...
  end

  def self.private_class_method2
    ...
  end
)

Overall

I learned all the ways to declare private class methods in ruby through Troy’s article. There’s almost a style that will fit anyone coding style.

Go Forth & class << self; private; def method; end; end :-D