Неявный получатель - PullRequest
       11

Неявный получатель

0 голосов
/ 05 декабря 2018

Я читаю книгу Метапрограммирование Ruby и пытаюсь понять, как используются частные методы.Он имеет следующий абзац:

Во-первых, вам нужен явный получатель для вызова метода для объекта, который не является вами, а во-вторых, частные методы могут вызываться только с неявным получателем.

Может ли кто-нибудь дать мне пример, чтобы проиллюстрировать это: «вам нужен явный получатель для вызова метода для объекта, который не является вами»?

Ответы [ 3 ]

0 голосов
/ 05 декабря 2018

Ну, в общем, вы задаете два вопроса.Явный получатель / неявный получатель зависит от того, как вы вызываете метод.Вот пример:

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») приведет к ошибке, а также к попытке доступаэтот метод вне определения класса также вызовет частную ошибку метода.

надеюсь, это поможет:)

0 голосов
/ 05 декабря 2018

Я отвечу на ваш первый вопрос:

как используются частные методы

Частные методы чаще всего используются для предоставления методов для класса, которые доступны толькок другим методам в том же классе.Эти методы предназначены только для внутреннего использования классом и не могут вызываться извне.

0 голосов
/ 05 декабря 2018

В тексте, который вы цитируете, «не сам» означает не в том же контексте (объекте), что был сделан вызов.

В этом примере частного метода ...

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.Технически такая же функциональность (ни один получатель не совпадает с self как получатель), но Ruby реализует закрытые методы, запрещая явные получатели, даже self.Итак, как уже говорилось, частные методы нельзя вызывать с явным получателем.

Каждый раз, когда вы вызываете метод для объекта, вы не вызываете этот метод для себя (то есть для своего контекста).

'george'.upcase
=> "GEORGE"

Для upcase явный получатель - это часть перед точкой (строковый объект "george")

Если вы сделали

upcase

без указания получателя, этопредполагается, что вы хотите запустить upcase в своем контексте (self), который в IRB является основным: Object.Вот почему вы получаете

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