ruby

private and private_class_method keywords in Ruby


Why does private is applicable only for instance methods and isn't for the class methods? Not only that, why doesn't private_class_method method make the class methods private?

class Foo

  private

  def self.private_class_method
    puts 'hello from private_class_method'
  end


  def private_instace_method
    puts 'hello from private_instace_method'
  end
end

Foo.private_class_method #Ok!
Foo.new.private_instace_method #error: private method `private_instace_method' called for #<Foo:0x000001020873b8>

How about this?

class Foo

  private_class_method :private_class_method

  def self.private_class_method
    puts 'hello from private_class_method'
  end

  private

  def private_instace_method
    puts 'hello from private_instace_method'
  end
end

Foo.private_class_method #Ok!
Foo.new.private_instace_method #error: private method `private_instace_method' called for #<Foo:0x000001020873b8>

How do I make a class method private?


Solution

  • You can create a private class methods like this:

    class Foo
      def self.will_be_private
        # ...
      end
      private_class_method :will_be_private
    end
    

    Or like this:

    class Foo
      class << self
      private
        def will_be_private
          # ...
        end
      end
    end 
    

    While it is possible the make a class methods private, I can hardly think of a good reason to do so. IMO a private class method is a code smell and indicates that there is a thing that should be extracted into it own class.