2008-10-01 3 views
9

Каким образом Ruby допускает методы доступа класса за пределами класса неявно?Доступ к методу в Ruby

Пример:

class Candy 
    def land 
     homer 
    end 
end 

def homer 
    puts "Hello" 
end 

Candy.new.land #Outputs Hello 
+0

См. Http://www.sitepoint.com/rubys-top-self-object/ или https://banisterfiend.wordpress.com/2010/11/23/what-is-the-ruby-top-level/для подробного объяснения объекта верхнего уровня Ruby. – 2014-11-18 00:54:43

ответ

24

Определение метода «Гомер» добавляет метод к классу объектов. Он не определяет свободную функцию.

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

+0

См. Мои пояснения ниже ... Он определен в модуле ядра, а не в классе объектов. – nertzy 2010-04-22 00:08:34

4

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

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

+0

технически вы ошибаетесь, это определено на `Object` не на` Kernel`, `method (: homer) .owner => Object` – horseyguy 2011-09-25 02:14:57

5

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

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

    р Candy.ancestors # => [конфеты, объект, ядро]

  2. ли конфеты есть метод, называемый Homer?

    р Candy.instance_methods (ложь) .grep ("Гомер") # => []

    р Candy.private_instance_methods (ложь) .grep ("Гомер") # => []

  3. OK Candy не имеет метода, называемого «homer».

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

  5. Does объекта есть метод, называемый "Гомер"? p Object.instance_methods (false) .grep ("homer") # => []

    p Object.private_instance_methods (false).Grep ("Гомер") # => [ "Homer"]

Конфета имеет Объект в своей цепочке поиска, которая, в свою очередь, имеет частный метод экземпляра "Гомер", поэтому разрешение метод успешно

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

  1. Что такое self непосредственно перед тем, как Гомер определен?

    р сам # => главного Защиты Гомеры пут "Привет" конца

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

    р self.class # => Object

Который почему Гомер заканчивается на объекта

0

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

Смежные вопросы