Курс Raku / Об’єкти, введення-виведення та винятки / Класи та об’єкти / Ролі
Додавання ролі об’єкту
Роль не обов’язково вбудовувати в клас. Її можна надати й об’єктові,
який уже існує, за допомогою оператора but. Він підмішує
роль в один об’єкт під час виконання й повертає новий об’єкт, що цю роль
виконує:
role Loud {
method greet {
callsame().uc;
}
}
class Greeter {
method greet {
'Hello';
}
}
my $quiet = Greeter.new;
my $loud = Greeter.new but Loud;
say $quiet.greet; # Hello
say $loud.greet; # HELLOРоль отримав лише $loud. Клас Greeter і
кожен інший об’єкт Greeter лишилися недоторканими, тож
$quiet і далі вітається у звичайний спосіб. Коли і роль, і
клас визначають метод з однаковим іменем, перемагає версія ролі, а
callsame викликає ту, яку вона перекрила, — тут початковий
greet із Greeter, чий результат потім
переводять у верхній регістр.
Об’єкт, у який підмішано роль, розпізнається як такий, що її виконує:
say $quiet ~~ Loud; # False
say $loud ~~ Loud; # Truebut лишає початковий об’єкт таким, яким він був, і
віддає вам новий. Якщо ви радше хочете змінити наявний об’єкт на місці,
скористайтеся натомість оператором does:
my $speaker = Greeter.new;
$speaker does Loud;
say $speaker.greet; # HELLOПідмішування ролей в окремі об’єкти дозволяє вирішувати для кожного об’єкта зокрема, якої додаткової поведінки він має набути, — не визначаючи окремого класу для кожного поєднання.
Практика
Виконайте 1 тест за змістом цієї теми.
Навігація курсом
← Композиція кількох ролей | Тест — Ролі →
💪 Або перейдіть одразу до
вправ цього розділу.