Search code examples
rubyaccess-specifier

How to create a private class method?


How come this approach of creating a private class method works:

class Person

  def self.get_name
    persons_name
  end

  class << self

    private

    def persons_name
      "Sam"
    end
  end
end

puts "Hey, " + Person.get_name
puts "Hey, " + Person.persons_name  #=> raises "private method `persons_name' called for Person:Class (NoMethodError)"

But this does not:

class Person

  def self.get_name
    persons_name
  end

  private

  def self.persons_name
    "Sam"
  end
end

puts "Hey, " + Person.get_name
puts "Hey, " + Person.persons_name

Solution

  • private doesn't seem to work if you are defining a method on an explicit object (in your case self). You can use private_class_method to define class methods as private (or like you described).

    class Person
      def self.get_name
        persons_name
      end
    
      def self.persons_name
        "Sam"
      end
    
      private_class_method :persons_name
    end
    
    puts "Hey, " + Person.get_name
    puts "Hey, " + Person.persons_name
    

    Alternatively (in ruby 2.1+), since a method definition returns a symbol of the method name, you can also use this as follows:

    class Person
      def self.get_name
        persons_name
      end
    
      private_class_method def self.persons_name
        "Sam"
      end
    end
    
    puts "Hey, " + Person.get_name
    puts "Hey, " + Person.persons_name