隐式接收器

时间:2018-12-05 12:20:44

标签: ruby private implicit

我正在阅读 Metaprogramming Ruby 一书,并试图了解如何使用私有方法。它具有此段:

  

首先,您需要一个显式的接收方来在非对象上调用方法   第二,私有方法只能由隐式接收者调用。

谁能给我一个例子来说明“您需要一个显式的接收者来对不是您自己的对象调用方法”?

3 个答案:

答案 0 :(得分:2)

在文本中引述“不是你自己”意味着不在调用的同一上下文(对象)中。

在此私有方法示例中...

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方法正在包含baz方法的同一对象上调用bar(即,如果您在编写代码时认为自己坐在对象中,则称为“自身”或“自己”)对象的方法)。

现在将类重写为...

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

现在您看到bar不再起作用,因为您在方法self中对baz的调用上使接收者bar(显式接收者)特权了。从技术上讲,功能完全相同(没有接收者与接收者本身相同),但是Ruby通过禁止显式接收者(甚至是self)来实现私有方法。因此,如上所述,私有方法不能用显式接收器调用。

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

'george'.upcase
=> "GEORGE"

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

如果您这样做

upcase

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

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

答案 1 :(得分:1)

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

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'

此代码将两次打印“此处的某些文本”,一次不进行显式调用,一次不进行显式调用。

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

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”)访问私有方法将导致错误,并且尝试在类定义之外访问该方法也将导致私有方法错误。

希望它会有所帮助:)

答案 2 :(得分:0)

我将回答您的第一个问题:

  

如何使用私有方法

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