在阅读this article之前,我认为Ruby中的访问控制是这样工作的:

  • public-可被任何对象访问(例如Obj.new.public_method)
  • protected-只能从对象本身以及任何子类内部访问
  • private-与protected相同,但该方法不存在于子类中

然而,protectedprivate的行为似乎是相同的,除了不能用显式接收器调用private方法(即self.protected_method工作,但self.private_method不工作).

这有什么意义?什么时候会出现不希望用显式接收器调用方法的情况?

推荐答案

定义类或其子类的任何实例都可以调用protected个方法.

private个方法只能从调用对象内部调用.不能直接访问另一个实例的私有方法.

下面是一个快速实用的例子:

def compare_to(x)
 self.some_method <=> x.some_method
end

some_method在这里不可能是private.它必须是protected,因为需要它来支持显式接收器.典型的internal helper方法通常可以是private,因为它们永远不需要这样调用.

重要的是要注意,这与java或C++的工作方式不同.Ruby中的private类似于Java/C++中的protected,因为子类可以访问该方法.在Ruby中,无法像Java中的private那样限制从子类访问方法.

无论如何,Ruby的可见性在很大程度上是一个"建议",因为你总是可以使用send:

irb(main):001:0> class A
irb(main):002:1>   private
irb(main):003:1>   def not_so_private_method
irb(main):004:2>     puts "Hello World"
irb(main):005:2>   end
irb(main):006:1> end
=> nil

irb(main):007:0> foo = A.new
=> #<A:0x31688f>

irb(main):009:0> foo.send :not_so_private_method
Hello World
=> nil

Ruby相关问答推荐

在Glade创建的UI中以编程方式填充GtkTreeView

环绕分隔线,保留第一列,最小最终长度

有没有一种简单的方法可以在 Ruby 中获取图像尺寸?

何时在 Ruby 方法中使用 `self.foo` 而不是 `foo`

Ruby 中的字符串是可变的吗?

Ruby 在与源相同的目录中加载配置(yaml)文件

使用正则表达式在第一个逗号之前提取文本

`require': no such file to load in ruby

Vagrant - 如何拥有特定于主机平台的配置步骤

需要必要的库和/或头文件时如何安装 ruby​​-debug

array.include?多个值

线程安全:Ruby 中的类变量

使用 Ruby,我如何迭代一个 for 循环 n.times

. vs ::(点与双冒号)用于调用方法

ruby module_function 与包含模块

Sinatra 登录?

错误数量的参数(1 代表 0)在 Ruby 中是什么意思?

Ruby中的urldecode?

要散列的散列数组

JavaScript Array:获取项目的范围