Moose :: Role - простой способ расширить применение роли? - PullRequest
5 голосов
/ 31 октября 2010

У меня есть Moose::Role, который я хотел бы назвать некоторыми дополнительными подпрограммами в классе, когда эта роль применяется к классу.

Существует ли простой способ изменить то, что происходит, когда роль применяетсябез необходимости копаться в кодировке Moose::Meta::Role?В идеале, я бы просто хотел after 'apply' => ... добавить дополнительный материал.

Редактировать:

Я специально использую это с определением результата DBIx::Class::Core, чтобы создать что-то вроде компонентаэто также изменяет конструктор.Я бы просто написал его как компонент, если бы смог получить результат BUILDARGS и BUILD, но я не могу этого сделать.Таким образом, вместо выполнения load_component, я выполняю with 'role', но некоторые эффекты компонента заключаются в добавлении belongs_to отношений к классу.Поэтому я подумал, что лучший способ сделать это - применить роль к классу.

Ответы [ 3 ]

4 голосов
/ 31 октября 2010

В кратком комментарии я отослал вас к этому вопросу , в котором обсуждается, как получить доступ к метаклассу класса, к которому применяется роль (например, чтобы вы могли условно построить класс). Однако это действительно вонючее использование MooseX :: Role :: Parameterized, предоставляющее вам эту информацию, и оно также не будет работать, если роль применяется к другой роли, а не к классу.

В качестве альтернативы вы можете написать сахарную функцию, которая получает метаинформацию, и построить класс следующим образом:

sub foo
{
     my ($meta, %options) = @_;

     # based on what is present in %options, add additional attributes...
     $meta->add_attribute(...);
}

См. Moose :: Cookbook :: Extending :: Recipe4 для примера написания функций сахара.

1 голос
/ 31 октября 2010

Вы можете использовать параметризованную роль .Пример того, как получить доступ к классу потребления, приведен в учебнике .При этом я бы посоветовал вам присоединиться к IRC-каналам Moose и DBIx-Class или спискам рассылки, чтобы найти лучшие практики в этом отношении.

0 голосов
/ 01 ноября 2010

Я обнаружил, что это работает, компактно и, похоже, соответствует намерениям, изложенным в документах, - использовать черту для изменения мета-роли, используемой моей конкретной ролью:

package DBIx::Class::Meta::Role::MyRole;
use Moose;
BEGIN { extends 'Moose::Meta::Role'; }
after 'apply' => sub {
## ..my mods to add extra relationships to DBIx::Class::Core result
};
no Moose;

package DBIx::Class::MyRole;
use Moose::Role -metaclass => 'DBIx::Class::Meta::Role::MyRole';
...