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
>