prepend и разрешение методов
Цепочки предков
«prepend и разрешение методов» — бесплатный урок Ruby Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Ruby Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Ruby Academy содержит 4 уроков всего.
Цепочки предков
Когда Вы вызываете метод, Ruby ищет его в списке, который называется цепочкой предков. Побеждает первое найденное определение. Понимание этой цепочки объясняет взаимодействие миксинов и наследования.
class Animal; end
class Dog < Animal; end
p Dog.ancestorsПорядок поиска методов
Сначала Ruby ищет метод в классе объекта, затем в подключённых модулях, потом в родительском классе и так далее по цепочке, пока не найдёт метод.
module M
def hello; "from module"; end
end
class C
include M
def hello; "from class"; end
end
puts C.new.helloinclude находится ниже класса
Подключённый модуль с помощью include располагается сразу под классом в цепочке. Собственные методы класса имеют приоритет над методами модуля.
module M; end
class C
include M
end
p C.ancestors # [C, M, Object, ...]Знакомство с prepend
prepend вставляет модуль выше класса в цепочке. Теперь методы модуля находятся первыми, раньше собственных методов класса.
module M
def hello; "from module"; end
end
class C
prepend M
def hello; "from class"; end
end
puts C.new.helloprepend в цепочке
Изучите предков, чтобы увидеть, как prepend помещает модуль перед классом.
module M; end
class C
prepend M
end
p C.ancestors # [M, C, Object, ...]super из модуля, добавленного через prepend
Поскольку добавленный через prepend модуль выполняется первым, он может обернуть метод класса, вызвав super для обращения к исходному методу. Это идеально подходит для добавления дополнительного поведения.
module Logged
def save
puts "before save"
result = super
puts "after save"
result
end
end
class Record
prepend Logged
def save
puts "saving record"
:ok
end
end
p Record.new.savesuper в миксинах
super следует по цепочке предков. Из подключённого модуля super переходит к родительскому классу, а из модуля, добавленного через prepend, — непосредственно к самому классу.
module Polite
def greet; "Hi! " + super; end
end
class Person
prepend Polite
def greet; "I am here."; end
end
puts Person.new.greetОбёртка без редактирования
prepend позволяет добавить поведение вокруг существующих методов, не изменяя исходный код класса. Это аккуратная альтернатива обезьяньему патчингу.
module Timing
def compute(n)
puts "start"
super
end
end
class Calc
prepend Timing
def compute(n); n * n; end
end
puts Calc.new.compute(5)Порядок нескольких модулей
Если подключено несколько модулей, последний подключённый располагается ближе всего к классу и ищется первым.
module A; def who; "A"; end; end
module B; def who; "B"; end; end
class C
include A
include B
end
puts C.new.who # B wins (included last)
p C.ancestorsИтоги: include и prepend
Сравним:
include M: цепочка выглядит так:[Class, M, ...]— методы класса имеют приоритет.prepend M: цепочка выглядит так:[M, Class, ...]— методы модуля имеют приоритет и могут вызватьsuperдля перехода в класс.
module M; end
class Inc; include M; end
class Pre; prepend M; end
p Inc.ancestors
p Pre.ancestorsСобираем всё вместе
Разрешение методов следует по цепочке предков:
- Методы класса имеют приоритет над подключёнными модулями.
- Модули, добавленные через
prepend, имеют приоритет над классом. superпереходит на один шаг вверх по цепочке.
module Cap
def name; super.capitalize; end
end
class User
prepend Cap
def name; "ada"; end
end
puts User.new.nameБыстрая проверка
Проверьте, насколько хорошо Вы поняли разрешение методов.
Повторение
Вы изучили разрешение методов:
- Ruby ищет методы в цепочке предков сверху вниз.
includeрасполагается ниже класса, аprepend— выше него.superобращается к следующему определению выше по цепочке.prependпозволяет аккуратно оборачивать методы.
module Loud
def speak; super.upcase; end
end
class Bot
prepend Loud
def speak; "beep"; end
end
puts Bot.new.speakЧасто задаваемые вопросы
Урок «prepend и разрешение методов» бесплатный?
Да — полный текст урока «prepend и разрешение методов» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Ruby Academy, подпишись на CoddyKit PRO. Курс Ruby Academy содержит 4 уроков всего.
Чему я научусь в уроке «prepend и разрешение методов»?
Цепочки предков Ты практикуешь Ruby Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Ruby Academy?
Предыдущий опыт не требуется. Ruby Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «prepend и разрешение методов»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Ruby Academy?
Да. Каждый урок Ruby Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Определение модулей
- include и extend
- Comparable и Enumerable
- prepend и разрешение методов