为什么实例方法" protected_class_method"并不存在"模块" Ruby中的类,而" public_class_method"和" private_class_method"实例方法确实存在于"模块"类?
这不遵循"私有","受保护"和"公共"的模式。实例方法都是为"模块"类。
答案 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