Курс языка программирования 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, о которой шла речь в предыдущей теме, — метаметоды для исследования.

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

Тест — Протокол метаобъектов   |   Найдите метод


💪 Или перейдите сразу к упражнениям этого раздела.