Delegationを使わないでNon-Mooseクラスを継承

FAQにもあるけど、Moose::Objectも継承して->meta->new_objectを明示的に呼ぶことにより、delegationを使わないでNon-Mooseクラスを継承することもできる。

use strict;
use warnings;
{
    package Parent;
    
    sub new {
        my ($class, %args) = @_;
        
        bless {name => $args{name}}, $class;
    }
}
 
{
 
    package Child;
 
    use Moose;
    extends qw(Parent Moose::Object);
    no Moose;
 
    sub new {
        my $class = shift;
        my $obj = $class->SUPER::new(@_);
        return $class->meta->new_object(
            __INSTANCE__ => $obj,
            @_,
        );
    }
 
    __PACKAGE__->meta->make_immutable;
}
 
my $obj = Child->new(name => 'foo');
warn $obj->{name};

こんな感じだけど、Parentがuse fieldsしてる場合にはやっぱりdelegationを使わないとダメなそうだ。

use strict;
use warnings;
{
    package Parent;
    use fields qw(name);
 
    sub new {
        my ($class, %args) =@_;
        my $self = ref $class ? $class : fields::new($class);
        $self->{name} = $args{name};
        $self;
    }
}
...

こんな感じにParentがuse fieldsしてると

Pseudo-hashes are deprecated at subclass.pl line 10.
No such pseudo-hash field "name" at subclass.pl line 10.

と怒られる。
jrockway曰くfieldsの非互換性をMooseで知る術がないからだそうな。
ぶっちゃけfieldsが何やってんのかよくわかってないのでそーゆーもんだと覚えた。