隐式接收者

Implicit receiver

我正在阅读 元编程 Ruby 一书,并试图了解如何使用私有方法。它有这段:

first, you need an explicit receiver to call a method on an object that is not yourself, and second, private methods can be called only with an implicit receiver.

谁能给我一个例子来说明这一点"you need an explicit receiver to call a method on an object that is not yourself"?

在您引用的文本中,"not yourself" 表示不在与调用相同的上下文(对象)中。

在这个私有方法的例子中...

class Foo
  def bar
    baz
  end
  private
  def baz
    'hello'
  end
end

如果你这样做

Foo.new.baz

你得到一个错误,因为 baz 是用一个明确的接收者调用的(点之前的部分...Foo.new

如果你这样做

Foo.new.bar
=> "hello"

之所以可行,是因为方法 bar 在没有接收者的情况下调用了 baz。它能够在没有接收者的情况下调用它,因为 bar(如 baz)都是 Foo 对象的实例方法,因此它们具有相同的上下文(相同的 self ). bar 方法在包含 bar 方法的同一对象上调用 baz(即 "itself" 或 "yourself",如果您认为自己坐在对象中当您编写对象的方法时)。

现在将 class 重写为...

class Foo
  def bar
    self.baz
  end
  private
  def baz
    'hello'
  end
end

现在你看到 bar 不再有效,因为你在方法 bar.从技术上讲,功能完全相同(没有接收者与接收者自身相同),但 Ruby 通过禁止显式接收者实现私有方法,甚至 self。因此,如前所述,不能使用显式接收器调用私有方法。

每次您调用一个对象的方法时,您并不是在自己(即您的上下文)上调用该方法。

'george'.upcase
=> "GEORGE"

对于upcase,显式接收者是点之前的部分(字符串对象"george")

如果你这样做了

upcase

在不指定接收者的情况下,它假定您想要 运行 upcase 在您的上下文 (self) 中,在 IRB 中是 main:Object。这就是为什么你得到

NameError: undefined lcoal variable or method `upcase' for main:Object

嗯,基本上你是在问两个问题。 显式 receiver/implicit 接收器取决于您如何调用该方法。 这是一个例子:

class MyClass
    def method1
        self.method2 # explicit reciever 'self'
        method2 # we call the same method but we don't pass a reciever -> implicit reciever
    end

    def method2
        puts "some text in here"
    end
end

mc_object = MyClass.new
mc_object.method1 # explicit reciever 'mc'

此代码将打印 "some text in here" 两次,一次有显式调用,一次没有。

现在,ruby 中的私有方法是只能在 class 自身内部调用的方法,并且在这样做时您只能使用隐式接收器。 在下一个示例中,我们将添加一个新的私有方法。

class MyClass
    def method1
        self.method2 # explicit reciever 'self'
        method2 # we call the same method but we don't pass a reciever => implicit reciever

        method3 # will work - implicit reciever
        self.method3 # will not work! - private method `method3' Error
    end

    def method2
        puts "some text in here"
    end

    private

    def method3
        puts "this text is private!"
    end
end
mc_object = MyClass.new
mc_object.method1 # explicit reciever 'mc'
mc_object.method3 # will not work! - private method `method3' Error 

因此您可以看到,尝试访问带有接收器(前缀 'self')的私有方法会导致错误,并且尝试访问 class 定义之外的方法也会导致错误私有方法错误。

希望对您有所帮助:)

我会回答你的第一个问题:

how private methods are used

私有方法最常用于为 class 提供只能由同一 class 中的其他方法访问的方法。这些方法仅供 class' 内部使用,不能从外部调用。