Grokbase
x

Non-Moose metaclasses

View TopicPrint | Flat  Thread  Threaded
1) Jesse Luehrs So, after a discussion with mst in #moose, he pointed out that initializing a non-Moose class with...
| +1 vote (Anchor)
[ Profile | Reply to group ] [ Flat  Thread  Threaded ]
So, after a discussion with mst in #moose, he pointed out that
initializing a non-Moose class with a Moose metaclass is a bug, and we
really shouldn't be doing it. This occurs quite a bit in code within
CMOP and Moose, which does things like:

  for my $class ($self->linearized_isa) {
      my $meta = $self->initialize($class);
      ...
  }

and similarly with $self->superclasses, etc. When called on a Moose
class, this will initialize any non-Moose ancestors with a metaclass of
Moose::Meta::Class, which isn't really correct.

I looked into this, and it seems like the only way to accomplish this
safely is to not cache metaclasses which aren't explicitly initialized.
I've implemented this on the topic/nonmoose_gets_cmop_meta branches of
CMOP and Moose (the name is from an earlier attempt which used a
different strategy). It seems to work properly, and fixes the issues
that I've been able to find, but I was wondering if people think this is
a sane thing to want to do, or if this is going to cause other issues
down the road.

Another possible solution to this problem would be to force all classes
which get incidentally initialized like this to have CMOP metaclasses,
but this tends to break in complicated inheritance situations - for
instance, Moose::init_meta won't reinitialize a class with a CMOP
metaclass to have a Moose metaclass, it just throws an error (probably
since upgrading the metaclass in a safe way that preserves things like
existing attributes and such would be a pain). Also, in some situations,
the temporary metaclass needs to be a Moose::Meta::Class -
_fix_metaclass_incompatibility for instance doesn't exist in CMOP, so in
a Moose - non-Moose - Moose inheritance setup, the non-Moose class needs
to get a Moose metaclass to run _fix_metaclass_incompatibility on to see
if it is going to need fixing (this isn't a big deal, since metaclass
compatibility means that it needs to have a Moose metaclass anyway, but
still something to watch out for).

So... any thoughts?

-doy
2) Jesse Luehrs Actually, I've thought some more about this, and disregard this last paragraph. This here is the...
| +1 vote (Anchor)
[ Profile | Reply to group ] [ Flat  Thread  Threaded ]
On Sun, Feb 07, 2010 at 01:37:16PM -0600, Jesse Luehrs wrote:
> So, after a discussion with mst in #moose, he pointed out that
> initializing a non-Moose class with a Moose metaclass is a bug, and we
> really shouldn't be doing it. This occurs quite a bit in code within
> CMOP and Moose, which does things like:
>
>   for my $class ($self->linearized_isa) {
>       my $meta = $self->initialize($class);
>       ...
>   }
>
> and similarly with $self->superclasses, etc. When called on a Moose
> class, this will initialize any non-Moose ancestors with a metaclass of
> Moose::Meta::Class, which isn't really correct.
>
> I looked into this, and it seems like the only way to accomplish this
> safely is to not cache metaclasses which aren't explicitly initialized.
> I've implemented this on the topic/nonmoose_gets_cmop_meta branches of
> CMOP and Moose (the name is from an earlier attempt which used a
> different strategy). It seems to work properly, and fixes the issues
> that I've been able to find, but I was wondering if people think this is
> a sane thing to want to do, or if this is going to cause other issues
> down the road.

Actually, I've thought some more about this, and disregard this last
paragraph.

> Another possible solution to this problem would be to force all classes
> which get incidentally initialized like this to have CMOP metaclasses,
> but this tends to break in complicated inheritance situations - for
> instance, Moose::init_meta won't reinitialize a class with a CMOP
> metaclass to have a Moose metaclass, it just throws an error (probably
> since upgrading the metaclass in a safe way that preserves things like
> existing attributes and such would be a pain). Also, in some situations,
> the temporary metaclass needs to be a Moose::Meta::Class -
> _fix_metaclass_incompatibility for instance doesn't exist in CMOP, so in
> a Moose - non-Moose - Moose inheritance setup, the non-Moose class needs
> to get a Moose metaclass to run _fix_metaclass_incompatibility on to see
> if it is going to need fixing (this isn't a big deal, since metaclass
> compatibility means that it needs to have a Moose metaclass anyway, but
> still something to watch out for).

This here is the actual correct solution. The issues I brought up here
are all really just bugs in our metaclass compat code, that really
should be fixed. I'll see about having another shot at this sometime
later this week.

> So... any thoughts?
>
> -doy

-doy
spacer
View TopicPrint | Flat  Thread  Threaded
Home > Groups > Moose > Non-Moose metaclasses (2 posts)