0Pricing
Ruby Academy · Урок

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.hello

include находится ниже класса

Подключённый модуль с помощью 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.hello

prepend в цепочке

Изучите предков, чтобы увидеть, как 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.save

super в миксинах

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 — локальная установка не требуется.

Все уроки этого курса

  1. Определение модулей
  2. include и extend
  3. Comparable и Enumerable
  4. prepend и разрешение методов
← Назад к Ruby Academy