Курс языка программирования 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 тест по содержанию этой темы.
Навигация по курсу
← Композиция нескольких ролей | Тест — Роли →
💪 Или перейдите сразу к
упражнениям этого раздела.