Курс Raku / Об’єкти, введення-виведення та винятки / Класи та об’єкти / Протокол метаоб’єктів 🆕

Додавання методів під час виконання

MOP існує не лише для дослідження — він може й змінювати тип, поки програма виконується. Метаметод .^add_method додає до класу новий метод:

class Empty {
}

Empty.^add_method('greet', method { 'hi' });

say Empty.new.greet; # hi

Клас Empty визначено взагалі без методів. Далі Empty.^add_method('greet', …) приєднує метод на ім’я greet, заданий як анонімний method { … }. Від цієї миті кожен об’єкт Empty відгукується на .greet, наче метод було вписано в клас.

Це справжнє метапрограмування: метаоб’єктові для Empty кажуть виростити новий метод. Той самий протокол лежить в основі можливостей, якими ви вже користувалися: концептуально, коли ви пишете class, role, has чи method, компілятор будує ваш тип за вас через методи MOP на кшталт .^add_method та .^add_attribute.

«Концептуально» — бо це модель мови, а не обіцянка щодо якогось конкретного компілятора. MOP є тим, у термінах чого об’єктну систему специфіковано; чи справді дана реалізація буквально пропускає кожне оголошення через ці метаметоди — і чи можна це спостерегти — залежить від неї. З тієї самої причини виклик цих метаметодів вами самими є залежним від реалізації: які з них компілятор надає й як саме вони поводяться, може різнитися, тож код, що звертається до .^add_method та йому подібних, може працювати не однаково в кожному Raku.

Додавання методів під час виконання — потужний і рідко потрібний інструмент. Більшість програм ніколи до нього не вдається, але саме він робить об’єктну систему Raku відкритою: правила класів самі записані в термінах MOP, тож ви можете їх розширювати. Для щоденного коду тією частиною MOP, якою ви справді користуватиметеся, є метаметоди дослідження з попередньої теми.

Навігація курсом

Тест — Протокол метаоб’єктів   |   Знайдіть метод


💪 Або перейдіть одразу до вправ цього розділу.