How to create a private class method?

后端 未结 8 1314
北荒
北荒 2020-12-02 04:43

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

class Person

  def self.get_name
    persons_name
  end

  class << self

    private         


        
相关标签:
8条回答
  • 2020-12-02 05:10

    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
    
    0 讨论(0)
  • 2020-12-02 05:13

    I too, find Ruby (or at least my knowledge of it) short of the mark in this area. For instance the following does what I want but is clumsy,

    class Frob
        attr_reader :val1, :val2
    
        Tolerance = 2 * Float::EPSILON
    
        def initialize(val1, val2)
            @val2 = val1
            @val2 = val2
            ...
        end
    
        # Stuff that's likely to change and I don't want part
        # of a public API.  Furthermore, the method is operating
        # solely upon 'reference' and 'under_test' and will be flagged as having
        # low cohesion by quality metrics unless made a class method.
        def self.compare(reference, under_test)
            # special floating point comparison
            (reference - under_test).abs <= Tolerance
        end
        private_class_method :compare
    
        def ==(arg)
            self.class.send(:compare, val1, arg.val1) &&
            self.class.send(:compare, val2, arg.val2) &&
            ...
        end
    end
    

    My problems with the code above is that the Ruby syntax requirements and my code quality metrics conspire to made for cumbersome code. To have the code both work as I want and to quiet the metrics, I must make compare() a class method. Since I don't want it to be part of the class' public API, I need it to be private, yet 'private' by itself does not work. Instead I am force to use 'private_class_method' or some such work-around. This, in turn, forces the use of 'self.class.send(:compare...' for each variable I test in '==()'. Now that's a bit unwieldy.

    0 讨论(0)
提交回复
热议问题