Hi,

I think that this is a related question.  I seem to be grappling with
similar things that Mike is.  ( No not the alcohol or the lack of sleep. )

What I want to do provide a consuming class with a
  a) a meta-attribute (via a trait).
  b) methods to the meta-class.

I think the answer is to use Moose::Exporter and/or
Moose::Util::MetaRole::apply_metaroles.  This doesn't work, but something
like:

    package My::Role

        use Moose::Role;
        Moose::Exporter->setup_import_methods(
            also => 'Moose',
                        attribute => ['My::MetaAttribute::Role'] ,





Correct me if I am I think that my first observation is that




I think that the answer is NO.  But it would be nce since the
Moose::Exporter is not called on the consumption of a role.

I understand your answer, but what if you wanted a role to cause the
installation of

Is there a way to have a role cause the





Christopher Brown
Principal
Open Data
 http://www.opendatagroup.com
 http://blog.opendatagroup.com


On Sun, May 9, 2010 at 4:29 AM, Jesse Luehrs <[email protected]> wrote:

> On Sun, May 09, 2010 at 04:56:21AM -0400, Mike Friedman wrote:
> > Greetings,
> >
> > I've got a class X. X has a metaclass M. I want M to make X do role Y.
> > That's it. I have been banging my head against a half dozen Moose
> > documentation pages but can't seem to puzzle out this seemingly simple
> > operation.
>
> So... is there a reason that using 'with' in the class definition isn't
> sufficient? (The subject line mentions runtime application, but your
> code sample below is a Moose::Exporter package, which seems to be
> counter to that idea.)
>
> > Which one of these things do I need to use? Moose::Exporter,
> > Moose::Util::MetaRole? (This seems to be about meta roles rather than
> > roles, but I don't _think_ I need to use a meta role to just make a
> > class consume a given role, or do I?)
>
> Yes, MetaRole is for metaclass roles, as the name implies.
> Moose::Exporter is for if you want to make custom exporters (this can do
> what you want, see below, but there's really no need for it unless
> you're also doing other things like exporting functions or applying
> metaclass roles).
>
> > I also found this thing: Moose::Meta::Role::Application::ToClass which
> > sounds really nice but has zero documentation. I looked at the source
> > but, of course, I have no idea WTF is going on.
>
> This is an entirely internal class that you really should have no reason
> to use directly.
>
> > Here is one thing I tried, which doesn't seem to complain, but also
> > doesn't seem to apply the role. (In my test, the class does not cause
> > an exception even though it fails to implement a method required by
> > the role.)
>
> You were close - the reason this doesn't work is because initialize is
> for creating a metaclass for a class that doesn't yet have one; it's
> typically not very useful for roles. The thing you're looking for is
> Moose::Util::apply_all_roles, like so:
>
>  package MyApp;
>
>  use Moose ();
>  use Moose::Exporter;
>
>  use MyApp::Meta::Class;
>
>  Moose::Exporter->setup_import_methods(
>      with_meta  => [ 'handler' ],
>      also       => 'Moose',
>  );
>
>  sub init_meta {
>      my $class = shift;
>       my %options = @_;
>
>      my $meta = Moose->init_meta( @_ , metaclass => 'MyApp::Meta::Class' );
>       Moose::Util::apply_all_roles( $options{for_class}, 'MyApp::Role::App'
> );
>
>      return $meta;
>  }
>
>  ...
>
>  1;
>
> On another note, it's typically preferable to create metaclass traits
> rather than writing an actual metaclass yourself - this makes it work
> more nicely with other extensions (such as various MooseX modules). It
> probably won't harm anything if this is an app-specific metaclass
> extension that you're only writing one variation of, but it also
> wouldn't harm anything for it to be a role, and getting used to the good
> practice would probably help in the future. In that case, the exporter
> would look something like:
>
>  package MyApp;
>
>  use Moose ();
>  use Moose::Exporter;
>
>   my ($import, $unimport, $init_meta) =
> Moose::Exporter->setup_import_methods(
>       with_meta  => [ 'handler' ],
>      also       => 'Moose',
>       install    => [ 'import', 'unimport' ],
>      class_metaroles => {
>          class => [ 'MyApp::Meta::Trait::Class' ],
>      },
>  );
>
>  sub init_meta {
>      my ($package, %options) = @_;
>      Moose->init_meta(%options);
>      Moose::Util::apply_all_roles($options{for_class}, 'MyApp::Role::App');
>      goto $init_meta;
>  }
>
>  ...
>
>  1;
>
> -doy
>

Reply via email to