Вопрос

Как получается, что Ruby неявно разрешает методы доступа класса вне класса?

Пример:

class Candy
    def land
        homer
    end
end

def homer
    puts "Hello"
end

Candy.new.land #Outputs Hello
Это было полезно?

Решение

Определение метода «гомер» заключается в добавлении метода в класс Object.Это не определение свободной функции.

Класс Candy неявно наследуется от Object и поэтому имеет доступ к методам Object.Когда вы вызываете «гомер» в методе «земля», разрешение метода не может найти определение в текущем классе, переходит к суперклассу, находит метод, который вы добавили в объект, и вызывает его.

Другие советы

Простой способ узнать, что происходит

  1. Какие классы/модули ищутся для разрешения методов, используемых в объектах Candy?

    p Candy.ancestors #=> [Candy, Object, Kernel]

  2. Есть ли у Candy метод под названием Гомер?

    p Candy.instance_methods(false).grep("гомер") #=> []

    p Candy.private_instance_methods(false).grep("homer") #=> []

  3. OK Candy не имеет метода под названием «гомер».

  4. Что дальше в цепочке поиска (см. 1) => «Объект»

  5. Есть ли у Object метод под названием «Гомер»?p Object.instance_methods(false).grep("гомер") #=> []

    p Object.private_instance_methods(false).grep("гомер") #=> ["гомер"]

Candy имеет объект в своей цепочке поиска, который, в свою очередь, имеет частный метод экземпляра «homer», поэтому разрешение метода успешно.

А заявление о защите всегда определяет метод в классе чего угодно себя находится в точке определения

  1. Что себя непосредственно перед определением Гомера?

    p self #=> Main def Гомер ставит "Hello" End

  2. Так каков его тип?

    p self.class #=> Объект

Вот почему Гомер заканчивается Объект

Технически определение homer метод на самом деле находится на Kernel модуль, который смешивается с Object, не на Object напрямую.Так когда homer не является локальной переменной или методом экземпляра, определенным в Candy, цепочка наследования методов Ruby выполняется через Object а затем в смешанный Kernel модуль, а затем запускается этот код.

Редактировать: Извините, я не знаю, почему я так подумал.Похоже, метод действительно живет Object.Не уверен, что на практике это имеет большое значение, но мне следовало убедиться в этом, прежде чем публиковать информацию.

В Ruby нет свободно плавающих функций.Каждый метод принадлежит некоторому объекту.Методы, которые вы def на верхнем уровне фактически становятся методами экземпляра класса Object.Потому что все является Object на каком-то уровне все объекты имеют доступ к Objectметоды экземпляра.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top