为什么实例方法" protected_class_method"并不存在"模块" Ruby中的类?

时间:2018-01-30 20:03:08

标签: ruby

为什么实例方法" protected_class_method"并不存在"模块" Ruby中的类,而" public_class_method"和" private_class_method"实例方法确实存在于"模块"类?

这不遵循"私有","受保护"和"公共"的模式。实例方法都是为"模块"类。

3 个答案:

答案 0 :(得分:3)

对我来说,受保护的方法只作为实例方法才有意义。

受保护的方法可以由同一个类的其他实例调用。

class Student
  def initialize(age)
    @age = age
  end
  def older_than?(other)
    age > other.age
  end
  protected
  def age
    @age
  end
end

您无法直接在学生实例上调用age

student1 = Student.new(21)

student1.age
NoMethodError: protected method `age' called for #<Student:0x514d058 @age=21>

但是student1可以参考student2的年龄

student2 = Student.new(23)

student2.older_than?(student1)
 => true

因此,您可以看到实例的受保护方法唯一性如何从另一个实例引用它。

我看不出你会如何使用类“受保护的方法”......没有类似于上面的情况。

修改

感谢Cary Swoveland完全弄乱了我的想法,我意识到你可以做到以下几点......

class Class
  def show_k(klass)
    klass.k
  end
  protected
  def k
    "This is k"
  end
end

现在,如果我这样做

String.k 
NoMethodError: protected method `k' called for String:Class

但如果我这样做......

Integer.show_k(String)
=> "This is k"

可能因为类是Class类的实例。

我仍然不确定我是如何使用它的,但是你去了。

答案 1 :(得分:1)

让我们用一个类方法定义一个类。

class K
  def self.k
    'hi'
  end
end

def self.k只是在k的单例类中定义实例方法 K的简便方法。让我们这样做并保护它。

class K
  class << self
    protected def k
      puts 'hi'
    end
  end
end

我们找到了

K.k
  #=> NoMethodError: protected method `k' called for K:Class

调用此方法的唯一方法是(与私有方法一样)使用隐式接收器:

class K
  k
end
  #=> 'hi'

根据定义,单个类上定义的受保护实例方法可以由同一个类的实例调用,但是不能创建单个类的实例。

此行为与私有类方法相同,因此也不会有受保护的方法。

答案 2 :(得分:1)

如果考虑类方法中显式接收器的继承和使用,则在声明类方法(类的单例类上的实例方法)时,protected和private之间存在差异。使用Ruby 2.5测试以下样本。

class A
  class << self
    protected def pro
      puts 'pro'
    end
  end
end

class B < A
  class << self
    # Works
    def explicit_receiver_test
      self.pro
    end

    # Works
    def implicit_receiver_test
      pro
    end
  end
end

begin
  B.pro # Throws: NoMethodError
rescue NoMethodError => e
  puts e.message # Prints: protected method `pro' called for B:Class
end
B.explicit_receiver_test # Prints: pro
B.implicit_receiver_test # Prints: pro

class C
  class << self
    private def pri
      puts 'pri'
    end
  end
end

class D < C
  class << self
    # Fails
    def explicit_receiver_test
      self.pri
    end

    # Works
    def implicit_receiver_test
      pri
    end
  end
end

begin
  D.pri # Throws: NoMethodError
rescue NoMethodError => e
  puts e.message # Prints: private method `pri' called for D:Class
end
begin
  D.explicit_receiver_test # Throws: NoMethodError
rescue NoMethodError => e
  puts e.message # Prints: private method `pri' called for D:Class
end
D.implicit_receiver_test # Prints: pri