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