perlmroapi
СОДЕРЖАНИЕ
ИМЯ
perlmroapi - интерфейс плагина для разрешения методов Perl
ОПИСАНИЕ
Начиная с Perl 5.10.1, появился новый интерфейс для подключения и использования порядков разрешения методов, отличных от стандартного (линейный поиск в глубину). Порядок разрешения методов C3, добавленный в 5.10.0, был повторно реализован как плагин, без изменения интерфейса в пространстве Perl.
Каждый плагин должен регистрировать себя, предоставляя следующую структуру
struct mro_alg {
AV *(*resolve)(pTHX_ HV *stash, U32 level);
const char *name;
U16 length;
U16 kflags;
U32 hash;
}; и вызывая Perl_mro_register:
Perl_mro_register(aTHX_ &my_mro_alg); - resolve
-
Указатель на функцию линейной организации, описанную ниже.
- name
-
Имя MRO, в кодировках ISO-8859-1 или UTF-8.
- length
-
Длина имени.
- kflags
-
Если имя задано в UTF-8, установите это значение в
HVhek_UTF8. Значение передаётся напрямую в качестве параметра kflags функцииhv_common(). - hash
-
Предварительно вычисленное значение хэша для имени MRO или 0.
Обработчики
Функция resolve вызывается для генерации линеаризованного ISA для заданного хранилища, используя данный MRO. Она вызывается с указателем на хранилище и значением level, равным 0. Ядро всегда устанавливает level в 0 при вызове вашей функции — параметр предоставляется, чтобы ваша реализация могла отслеживать глубину, если ей требуется рекурсия.
Функция должна вернуть ссылку на массив, содержащий родительские классы в порядке следования. Имена классов должны быть результатом вызова HvENAME() для хранилища. В тех случаях, когда HvENAME() возвращает null, следует использовать HvNAME().
Вызывающая сторона отвечает за увеличение счетчика ссылок массива, возвращённого, если она хочет сохранить структуру. Следовательно, если вы создали временное значение, на которое не ссылаетесь, используйте sv_2mortal() для правильного удаления.
Если вы кэшируете возвращаемое значение, верните указатель на него без изменения счетчика ссылок.
Кэширование
Вычисление MRO может быть дорогостоящим. Реализация предоставляет кэш, в котором вы можете сохранить одно значение SV *, или любое значение, которое можно привести к типу SV *, например AV *. Чтобы прочитать ваше значение, используйте макрос MRO_GET_PRIVATE_DATA(), передав ему структуру mro_meta из хранилища и указатель на вашу структуру mro_alg:
meta = HvMROMETA(stash);
private_sv = MRO_GET_PRIVATE_DATA(meta, &my_mro_alg); Чтобы установить ваше значение, вызовите Perl_mro_set_private_data():
Perl_mro_set_private_data(aTHX_ meta, &c3_alg, private_sv); Кэш данных частного использования возьмет на себя управление ссылкой на частное значение private_sv, так же как hv_store() берёт на себя управление ссылкой на значение, которое вы ему передаёте.
Примеры
Примеры реализаций MRO см. в S_mro_get_linear_isa_c3() и в разделе BOOT: файла ext/mro/mro.xs, а также в S_mro_get_linear_isa_dfs() файла mro_core.c
АВТОРЫ
Реализация MRO C3 и переключаемых MRO в ядре Perl была написана Брэндоном Л. Блэком. Николас Кларк создал интерфейс плагина, переработал реализацию Брэндона, чтобы она работала с ним, и написал этот документ.
© 1993–2020 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.28.3/perlmroapi