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

Reply via email to