0
class Person
  def self.first_name
    puts "this is the first_name"
    second_name
  end
  private
  def self.second_name
    third_name
  end
  def self.third_name
    puts "this is the third name"
  end
end

how to make self.second_name call the self.third_name in the private methods

anothermh
  • 9,815
  • 3
  • 33
  • 52
  • Is there a reason why you're defining the private methods as class methods i.e. `def self.xxxx` rather than instance methods i.e. `def xxxx`? – Yule Nov 12 '19 at 16:53
  • 4
    Please take a moment to read https://stackoverflow.com/q/4952980/3784008 as your code does not work the way you think it does. – anothermh Nov 12 '19 at 17:08

1 Answers1

3

The method Module#private, in the body of a method, on a line by itself, causes all instances methods defined thereafter to be private until and if the method Module#public or Module#protected appears on a line by itself1. Class method definitions are unaffected.

Here are three ways to make a class method private.

#1. Use the method Module#private_class_method to make a public class method private

class Klass
  def self.class_meth1
    '#1'
  end
  private_class_method(:class_meth1)
end

Klass.class_meth1
  #=> NoMethodError (private method `class_meth1' called for Klass:Class)
Klass.send(:class_meth1)
  #=> "#1" 
Klass.singleton_class.private_method_defined?(:class_meth1)
  #=> true

Private instance methods in a class' singleton class are private class methods. See Object#singleton_class and Module#private_method_defined?.

#2. Define an instance method in the class' singleton class following the keyword private

class Klass
  class << self
    private
    def class_meth2
      '#2'
    end 
  end
end

Klass.singleton_class.private_method_defined?(:class_meth2)
  #=> true

#3. Include the keyword private in-line when defining an instance method in the class' singleton class

class Klass
  class << self
    private def class_meth3
      '#3'
    end 
  end
end

Klass.singleton_class.private_method_defined?(:class_meth3)
  #=> true

Note that private has no effect in the following, which creates a public class method:

class Klass
  private def self.class_meth
  end
end

Calling a private class method

In view of the foregoing discussion, this is what you need.

class Person
  def self.first_name
    puts "this is the first_name"
    second_name  
  end
  class << self
    private
    def second_name
      third_name
    end
    def third_name
      puts "this is the third name"
    end
  end
end

Person.first_name
this is the first_name
this is the third name

1. Module#private on a line by itself is of course disregarded if an instance method is defined with public or protected inline (e.g., public def meth...).

Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100