5

Ruby 作为一种面向对象的语言。这意味着无论我发送什么消息,我都严格将其发送到类的某个对象/实例上。

例子:

 class Test
   def test1
    puts "I am in test1. A public method"
    self.test2
   end

   def test2
    puts "I am in test2. A public Method"
   end
 end

有意义我test2self对象上调用方法

但我不能这样做

  class Test
   def test1
    puts "I am in test1. A public method"
    self.test2 # Don't work
    test2 # works. (where is the object that I am calling this method on?)
   end

   private
   def test2
    puts "I am in test2. A private Method"
   end
 end

我什么时候test2可以public method调用它self(很公平,一个发送给 self 对象的方法)。但是什么时候test2private method不能自己打电话。那么我发送方法的对象在哪里?

4

4 回答 4

11

问题

在 Ruby 中,不能用显式接收器直接调用私有方法;self 在这里没有得到任何特殊待遇。根据定义,当您调用时,self.some_method您将 self 指定为显式接收者,因此 Ruby 说“不!”

解决方案

Ruby 有其方法查找的规则。规则可能有更规范的来源(除了转到 Ruby 源),但这篇文在顶部列出了规则:

1) Methods defined in the object’s singleton class (i.e. the object itself)
2) Modules mixed into the singleton class in reverse order of inclusion
3) Methods defined by the object’s class
4) Modules included into the object’s class in reverse order of inclusion
5) Methods defined by the object’s superclass, i.e. inherited methods

换句话说,私有方法首先在 self 中查找,而不需要(或允许)显式接收器。

于 2012-05-30T08:21:12.220 回答
5

我发送方法的对象在哪里

self。如果您不指定接收者,则接收者为self.

Ruby 中的定义private是私有方法只能在没有接收者的情况下调用,即使用self. 有趣的是,该方法完全没有打扰您,该puts方法也是私有实例方法;-)

注意:此规则有一个例外。可以使用显式接收器调用私有设置器,只要接收器是self. 事实上,它们必须用显式接收器调用,否则局部变量赋值会产生歧义:

foo = :fortytwo      # local variable
self.foo = :fortytwo # setter
于 2012-05-30T10:34:44.050 回答
2

self表示您所在的对象的当前实例。

class Test
  def test1
    self
  end
end

调用Test.new.test1将返回类似#<Test:0x007fca9a8d7928>.
这是您当前使用的 Test 对象的实例。

将方法定义为私有意味着它只能在当前对象内部使用。
使用 时self.test2,您将离开当前对象(获取实例)并调用该方法。
因此,您正在调用私有方法,就好像您不在对象中一样,这就是您不能这样做的原因。

当您不指定self时,您将留在当前对象内。
所以你可以调用该方法。Ruby 足够聪明,知道这test2是一个方法而不是一个变量并调用它。

于 2012-05-30T07:46:43.873 回答
1

这在 Ruby 2.7(2019 年 12 月)中已更改:self.foo()现在对私有方法也有效foo

参考:

于 2020-06-14T13:48:40.680 回答