В первой части этого путешествия вы познакомились с анатомией магии (метапрограммирование) и увидели некоторые заклинания, которые можно накладывать с помощью магии метапрограммирования. В этом посте я покажу вам заклинания, которые вы можете использовать при работе с методами.

Заклинания метода

Заклинания, которые мы будем обсуждать в этом путешествии, — это заклинания, которые нам понадобятся при работе с методами.

1. псевдоним_метод

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

А что, если вы хотите изменить существующий метод, но все равно хотите использовать исходный метод в будущем? Ну, вот тут-то и появляется alias_method. Он используется для переименования методов в ruby. Посмотрим, как это работает.

2. метод_отсутствует

В приведенном выше примере мы создали класс Person. Все в порядке, когда мы вызывали метод name и name=. Так что же именно происходит, когда мы вызываем метод email? Сначала Ruby будет искать метод электронной почты в классе Person и, не найдя его там, будет искать метод электронной почты в суперклассе класса Person и далее по дереву наследования. Если Ruby находит метод в любом месте дерева наследования, то вызывается именно этот метод. Когда Ruby не удается найти метод, он разворачивается и вызывает второй метод. Этот второй вызов метода с несколько странным именем method_missing в конечном итоге генерирует исключение: это реализация method_missing по умолчанию, найденная в классе Object, которая вызывает исключение NoMethodError.

Однако вы можете переопределить method_missing в любом из ваших классов и самостоятельно обработать случай отсутствующего метода:

3. ответить_на_отсутствие?

respond_to? используется, чтобы определить, отвечает ли объект методу. Он часто используется для проверки того, что объект знает о методе перед его фактическим вызовом, чтобы избежать ошибки во время выполнения о существовании метода. Поскольку наш объект не знает об этих методах, но обрабатывается методом method_missing, мы должны переопределить двоюродный метод с именем respond_to_missing?

Чтобы иметь согласованный API при использовании method_missing, важно реализовать соответствующий response_to_missing?.

4. remove_method и undef_method

Чтобы удалить существующие методы, вы можете использовать метод remove_method в рамках данного класса. Если метод с тем же именем определен для предка этого класса, метод класса предка не удаляется. Метод undef_method, напротив, не позволяет указанному классу отвечать на вызов метода, даже если метод с тем же именем определен в одном из его предков.

5. отправить

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

Почему вы должны заботиться о методе отправки? Что ж, иногда вы точно не знаете, какие методы будут вызываться. Метод send обеспечивает общий способ вызова любого метода. Например, в приведенных ниже сборах за метод у нас много операторов if/else. Обратите внимание, что существует прямая связь между параметром школы и методом, который возвращает плату за эту школу.

Также обратите внимание, что по мере того, как мы добавляем новые школы, плата за обучение становится все больше и больше. Мы можем легко реорганизовать метод комиссий с помощью метода отправки. Давайте узнаем, как.

Вывод

Вы видели некоторые чудеса, которые можно использовать с методами. От псевдонимов методов до перехвата отсутствующих методов, ответа на отсутствующие методы, удаления/отмены определения методов и, наконец, динамического вызова методов с помощью отправки. Это очень мощные инструменты, но с силой приходит и большая ответственность. Вы не должны использовать их бездумно. В основном используйте их, только если нет лучших вариантов. То же самое относится и к другим инструментам метапрограммирования.

Первоначально опубликовано на goodheads.io. Найдите исходный пост здесь.