текст перекладу
Є три способи додавання методів з модуля до класу в Ruby.
Include
Цей метод додає методи як методи екземплярів
module Swimmable
def swim
"I can swim!"
end
end
class Fish
include Swimmable
end
fish = Fish.new
puts fish.swim # => "I can swim!"
puts Fish.ancestors # => [Fish, Swimmable, Object, Kernel, BasicObject]
Extend
Цей метод додає методи як методи класу
module Flyable
def fly
"I can fly!"
end
end
class Bird
extend Flyable
end
puts Bird.fly # => "I can fly!"
puts Bird.ancestors # => [Bird, Object, Kernel, BasicObject]
Prepend
Цей метод додає методи як методи екземплярів, але з вищим пріоритетом.
module Logger
def log_action
"Logged: #{super}"
end
end
class Action
prepend Logger
def log_action
"Some action"
end
end
action = Action.new
puts action.log_action # => "Logged: Some action"
puts Action.ancestors # => [Logger, Action, Object, Kernel, BasicObject]
Зазвичай, prepend визначається в кінці визначення класу.
Ви також можете prepend модуль поза визначенням класу
Action.prepend(Logger)
Послідовні prepend
module Formatter
def display
"Formatted: #{super}"
end
end
module Validator
def display
"Validated: #{super}"
end
end
class Report
prepend Formatter
prepend Validator
def display
"Report content"
end
end
report = Report.new
puts report.display # => "Validated: Formatted: Report content"
puts Report.ancestors # => [Validator, Formatter, Report, Object, Kernel, BasicObject]
Коли є кілька prepend, перший пошук здійснюється від останнього prepend.
Тому потік пошуку виглядатиме наступним чином.
prepend(n) -> prepend(n-1) -> class -> include(n) -> include(n-1)
Prepend використовується для вставки методів модуля на початку ланцюга пошуку методів класу, до методів самого класу. Це означає, що коли викликається метод, Ruby спочатку шукає його в препендованому модулі, а потім у самому класі.
Обгортка/Декорація методів
- Ідеально підходить для додавання поведінки перед/після існуючих методів
- Зазвичай використовується для логування, валідації, форматування тощо.
- Препендований метод може отримати доступ до оригінального методу через
super
Перевизначення методу з доступом до оригіналу
- На відміну від звичайного перевизначення методу, prepend дозволяє вам перевизначити метод і водночас отримати доступ до оригінального методу
- Корисно для модифікації значень, що повертаються, при збереженні оригінальної логіки
Множинна обробка шарів
- Можна ланцюжити кілька препендованих модулів
- Кожен модуль може обробляти результат наступного в ланцюгу
- Чудово підходить для побудови конвеєрів обробки
Налагодження та моніторинг
- Можна вставити код для налагодження без змін оригінальних класів
- Корисно для моніторингу продуктивності, відстеження викликів методів
Розширення фреймворків
- Дозволяє фреймворкам змінювати основну поведінку, зберігаючи доступ до оригінальних методів
- Може використовуватися для безпечного додавання функціональності до сторонніх гемів
Перекладено з: Include, extend and prepend in Ruby