Hi, I have a bit of a puzzle on my hands and I'm looking for some guidance.
Say you have a Moose base class Thing with various subclasses. Through
an oversight, one of these subclasses ('BadThing') isn't declared as a
Moose class - it just has the base class in its @ISA. (Sure, this is a
bug, but imagine it's one you didn't know was there).
BadThing doesn't define a constructor of its own. When I call
BadThing->new, I inherit 'new' from Moose::Object via Thing.
Moose::Object::new does this:
my $real_class = Scalar::Util::blessed($class) || $class;
my $self = Class::MOP::Class->initialize($real_class)->new_object($params);
at which point Class::MOP::Class spots that BadThing has no metaclass
and creates one for it - a Class::MOP::Class, not a
Moose::Meta::Class.
My instantiation of BadThing will probably succeed, because
Class::MOP::Class knows about quite a lot of the features that
Moose::Meta::Class knows about. But.. if I use a Moose-specific
feature, such as 'trigger', nothing will happen. I'll get no warning.
I'll just be stuck wondering why my trigger didn't fire.
So my question is, should Moose::Object::new complain if it tries to
instantiate a class whose metaclass is a non-Moose one?
In case I haven't been clear, here's a little script to illustrate:
use strict;
use warnings;
{
package Thing;
use Moose;
has 'name' => ( is => 'rw', trigger => \&name_changed );
sub name_changed {
my ( $self, $new, $old ) = @_;
$old //= q{I};
warn "$old shall henceforth be known as $new\n";
}
}
{
package BadThing;
our @ISA = qw( Thing );
}
my $t = Thing->new( name => 'Bert' );
$t->name( 'Ernie' );
my $bt = BadThing->new( name => 'Bernie' ); # This one won't fire the trigger
$bt->name( 'Ernst' );
Alex Francis