Курс по 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; # True

but оставя първоначалния обект какъвто си е бил и ви подава нов. Ако предпочитате да промените съществуващ обект на място, използвайте вместо това оператора does:

my $speaker = Greeter.new;
$speaker does Loud;
say $speaker.greet; # HELLO

Вмесването на роли в отделни обекти ви позволява да решавате обект по обект какво допълнително поведение да поеме — без да дефинирате отделен клас за всяка комбинация.

Практика

Направете 1 тест върху съдържанието на тази тема.

Навигация в курса

Композиране на няколко роли   |   Тест — Роли


💪 Или преминете направо към упражненията в този раздел.