我错过了什么吗?
class Circus
private
def start
puts 'And now for something completely different..'
end
end
我的幻灭:
c=Circus.new
c.start #NoMethodError: private method `start' called
c.method(:start).call #no problem at all
c.send :start #neither this fails
有人可以告诉我Ruby中存在私有方法的原因吗?
答案 0 :(得分:11)
这样说吧。在Ruby中,您可以轻松地将公共方法修补为调用私有方法的类,因此......为什么会 private
阻止您的行为?
您似乎认为private
方法在某种程度上是安全性,他们 在课堂外无法访问。封装不是关于安全性的,是一种用于生成干净,可维护代码的工具。由您来尊重类暴露的界面。如果您确实想要找到一种方法来调用私有方法,那么您将会这样做。 Ruby不能完全强制执行,也不应该这样做;这会适得其反,浪费时间。
我的意思是,任何人都可以给我至少一个为什么'私人'甚至存在于Ruby中的原因?
出于完全相同的原因{em}存在于任何其他基于OOP的语言:Encapsulation。真的,你认为只是因为你可以找到一种绕过private
的复杂方法,它应该被抛弃?
答案 1 :(得分:6)
它声明了该方法的意图。如果它是私人的,你不应该打电话给它,你应该知道这样做可能会导致不可预测或不良行为。
对于它的价值,这种行为不仅限于Ruby - 也可以通过Reflection API访问Java中的私有成员和变量。
答案 2 :(得分:0)
私有方法只能从同一个实例内部调用,而不需要显式接收器。无论何时提供显式接收器,它们都将失败,包括从同一实例调用的self.some_private_method
。通过send
绕过此功能的能力是一种非标准的编码实践,主要用于维护。
答案 3 :(得分:0)
一旦你开始使用反射,所有的赌注都会关闭。对于Ruby来说,这并不是唯一的,顺便说一下,几乎所有有反射的语言都有这个问题。
您可以使用编码标准和代码审核来缓解这种情况,例如:总是使用public_send
等。但是如果你不喜欢这样,你将需要使用具有正确分层反射系统的语言,例如Newspeak。