为什么我们在Ruby中有隐式接收器?

时间:2017-06-04 14:12:08

标签: ruby oop

我有两个关于Ruby核心OOP概念的问题。

  1. 我理解方法的显式调用(即self)和隐式调用(即没有初始化类对象或实例方法中的self)之间的区别。当我们有明确的接收器做一个非常整洁和明确的工作接收一个自我的方法(因为它引用当前的对象)而不是隐含的(我认为在诸如何时使用相同名称的方法或变量的情况下非常不确定初始化),那为什么我们仍然需要隐式调用方法?这只是一种偏好,还是因为正确使用私人和公共方法而必要?

  2. 通常,OOP私有方法绑定在类本身中,不能在子类或外部访问。但是,那些需要私有但又需要在子类中访问的方法然后在那里使用受保护的方法。但在Ruby中,私有和 受保护的方法在继承的类中访问,唯一的区别是私有方法只能被隐式调用,受保护的方法可以隐式或显式调用。我不明白这里的哲学只是因为ruby中的隐式调用功能,私有方法的一般定义不同?

2 个答案:

答案 0 :(得分:6)

我认为您对受保护方法的目的略有误解。可以从同一个类的另一个实例的方法调用受保护的方法。

class Person

  def initialize(name, age)
    @name = name
    @age = age
  end

  def older_than?(other_person)
    age > other_person.age
  end

  protected

  def age
    @age
  end

end

mother = Person.new('Carole', 34)
father = Person.new('George', 37)

如果你试试......

mother.age
=>NoMethodError: protected method `age' called for #<Person:0x0000000327daa0 @name="Carole", @age=34>

因此,您无法在外部调用#age方法。

但你可以做......

father.older_than?(mother)
=> true

因此father对象能够调用mother对象#age方法,因为他是同一个类Person的对象。

答案 1 :(得分:1)

在下面的讨论中,回想一下,使用隐式接收器(self)调用实例方法的唯一方法是在同一个类的实例方法中执行此操作。

问题是为什么Ruby被设计为允许使用隐式接收器调用大多数 1 实例方法。

人们可能不得不要求Matz获得权威答案,但我的猜测是它追溯到私有实例方法的实现方式。要求用隐式接收器调用它们(我猜是)是一种简单的方法来阻止它们从同一类的实例方法中的任何地方调用。

但是如果必须使用隐式接收器调用私有方法,为了保持一致性,允许(几乎所有)公共和受保护的实例方法使用隐式接收器调用是否有意义?

一些Rubiests认为使用显式接收器self是冗余的,因此使用隐式接收器(除非需要self.)。其他人认为使用隐式接收器作为混淆的潜在来源,因此使用self.,知道(或可能不知道),这是可选的。据我所知,Ruby中实现的所有核心Ruby方法都使用隐式接收器。那些在第一阵营的人可能会争辩说,冗余地使用self.类似于说“在蓝色的墙上遇见我是蓝色的”。

1有少数情况需要显式接收器self来避免歧义。最常见的两个是调用方法class(考虑class也是一个关键字)并调用一个setter,否则Ruby可能会将值分配给新创建的局部变量。另一个例子是我们不能编写Array方法def a; [1]; enddef a; [](1); end。同样,需要明确的接收者:self[1]self.[](1)