Ruby中的私有方法是什么?

时间:2013-06-13 13:11:25

标签: ruby

我错过了什么吗?

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中存在私有方法的原因吗?

4 个答案:

答案 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。