WedX - журнал о программировании и компьютерных науках

Модификаторы метода Perl Moose: вызовите «вокруг» до «до» и «после»

Я использую Moose, и мне нужно обернуть вызовы методов в моем проекте. Важно, чтобы мой код-оболочка был самым внешним модификатором. Что я сделал до сих пор, так это поместил модификаторы моего метода в роль Moose, а затем применил эту роль в конце моего класса следующим образом:

use Moose::Util;
Moose::Util::apply_all_roles(__PACKAGE__->meta, ('App:Roles::CustomRole'));
__PACKAGE__->meta->make_immutable;

Это позволяет мне быть достаточно уверенным, что мои модификаторы моей роли определены последними, что дает мне правильное поведение для «до» и «после». («До» и «после» в роли называются самые первые и самые последние.)

Первоначально я думал, что этого будет достаточно, но теперь мне действительно нужно обернуть методы аналогичным образом с «вокруг». Класс::MOP, на котором построен Moose, в первую очередь применяет модификаторы «вокруг», поэтому они вызываются после «до» и перед «после».

Для более подробной информации, вот текущий порядок вызова моих модификаторов:

CUSTOM ROLE before
    before 2
       before 1
           CUSTOM ROLE around
               around
                   method
               around
           CUSTOM ROLE around
       after 1
    after 2
 CUSTOM ROLE AFTER

Мне действительно нужно что-то вроде этого:

CUSTOM ROLE before
    CUSTOM ROLE around
        before 2
           before 1
               around
                   method
               around
           after 1
        after 2
    CUSTOM ROLE around
 CUSTOM ROLE AFTER

Любые идеи о том, как применить/вызвать мой модификатор «вокруг» там, где я хочу? Я знаю, что мог бы взломать таблицу символов (как это уже делает Class::MOP), но я бы не хотел этого делать.

09.11.2009

  • Я согласен с вопросом Эфира ниже, почему вы используете Moose::Util::apply_all_roles, а не with? 09.11.2009
  • Я хотел, чтобы модификаторы «до» и «после» в моей роли запускались самыми первыми или самыми последними по сравнению с другими модификаторами, которые могут уже существовать в классе. Применение роли вручную определяет модификаторы позже, а затем модификаторы запускаются первыми (для до) и последними (для после). 10.11.2009
  • @perigrin Наконец-то я понял ваш вопрос и вопрос Эфира. Мне не нужно применять роль с apply_all_roles, как я думал. Я все еще новичок в Moose и зациклился на идее необходимости применять роль вручную. Все, что мне действительно нужно было сделать, это применить with в конце файла (после других модификаторов), а не в начале. 10.11.2009

Ответы:


1

Самое простое решение - определить CUSTOM ROLE метод, который вызывает основной метод, а затем обернуть его.

role MyRole { 
    required 'wrapped_method';
    method custom_role_base_wrapper { $self->wrapped_method(@_) }

    around custom_role_base_wrapper { ... }
    before custom_role_base_wrapper { ... }
}

Проблема, с которой вы столкнулись, заключается в том, что вы пытаетесь использовать CUSTOM ROLE вокруг чего-то другого, чем метод. Это не то, для чего он предназначен. Помимо написания аналогичного взлома таблицы символов, как вы предложили (вероятно, вы могли бы убедить одного из людей Moose раскрыть API в Class:: MOP, чтобы помочь туда добраться), единственное другое решение, о котором я могу думать, это то, что выше.

Если вам не нужен дополнительный фрейм стека вызовов, который добавит custom_role_base_wrapper, посмотрите на Sub::Call::Tail или используя goto для управления стеком вызовов.

09.11.2009
  • В итоге я остановился на идее пользовательской оболочки. Это дало мне необходимую гибкость, спасибо. 24.11.2009

  • 2

    Я довольно новичок в Moose, но почему вы это делаете:

    use Moose::Util;
    Moose::Util::apply_all_roles(__PACKAGE__->meta, ('App:Roles::CustomRole'));
    

    а не просто это?

    with 'App:Roles::CustomRole';
    

    Что касается вашего вопроса, это немного хак, но не могли бы вы разделить свой метод around на методы before и after и применить роль в конце определения вашего класса (чтобы он применялся в нужном вам порядке)? Вы можете использовать частные атрибуты для сохранения состояния между двумя методами, если это абсолютно необходимо.

    09.11.2009
  • Проблема в том, что ни before, ни after не позволяют (чисто) изменить семантику возврата так, как это сделает around. Если эта семантика важна, вы облажались. Если это не так, почему вы используете around для начала? 09.11.2009
  • Причина, по которой я применяю его вручную, заключается в том, что модификаторы добавляются (и затем запускаются) в том порядке, в котором они определены. Как правило, вам все равно, какие модификаторы порядка выполняются. Но в моем случае я хотел, чтобы модификаторы моей роли были самыми первыми до и самыми последними после. Если вы используете синтаксис with для применения ролей, его модификаторы определяются первыми, и поэтому они будут выполняться как самые внутренние до и после. Применяя роль вручную в конце, они определяются последними и поэтому запускаются, когда я хочу, чтобы они были. 10.11.2009
  • @Matt: это действительно недостаток Moose. Возможно, семантика after должна позволять изменять возвращаемое значение, как это делает around, или следует изменить порядок методов before, around и after, чтобы все они были LIFO по отношению друг к другу, а не только друг к другу (если это имеет смысл) . 10.11.2009
  • before и after разработаны намеренно, чтобы не иметь подобных побочных эффектов. В частности, before и after предназначены для внеполосного поведения, связанного с методом, в то время как around предназначен только для переопределения этого типа метода. Подобная семантика трехлетней давности — это не то, что команда Moose приняла бы, и я не думаю, что это действительно ответ. 21.11.2009
  • Новые материалы

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

    ИИ в аэрокосмической отрасли
    Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


    Для любых предложений по сайту: [email protected]