xslate / p5-Mouse

Lightweight class builder for Perl, as a subset of Moose
https://metacpan.org/release/Mouse
Other
46 stars 32 forks source link

`required` is not applied with role consuming in run-time #88

Open potatogim opened 6 years ago

potatogim commented 6 years ago

Hello!

I'm trying to consume a role that has an attribute is specified required in run-time.

In Moose, it works gracefully but Mouse does not throw exception even though required attribute is not specified in constructor(MyPackage->new(...)).

sergeykolychev commented 6 years ago

@potatogim I am having problems to reproduce. Can you please add minimal example ?

potatogim commented 6 years ago

@sergeykolychev : Sure.

package MyRole;

use Moose::Role;

has 'name' =>
(
    is       => 'ro',
    isa      => 'Str',
    required => 1
);

no Moose::Role;

package MyClass;

use Moose;
use Moose::Util;

sub BUILD
{
    my $self = shift;
    my $args = shift;

    Moose::Util::apply_all_roles($self, 'MyRole');
}

__PACKAGE__->meta->make_immutable;

package main;

my $obj = MyClass->new();

1;

It throws an exception like below

Attribute (name) is required at /home/potatogim/.perl5/perlbrew/libs/perl-5.26.1@mop/lib/perl5/x86_64-linux-thread-multi/Moose/Util.pm line 113
    Moose::Util::apply_all_roles('Moose::Meta::Class::__ANON__::SERIAL::1=HASH(0x55616408ff98)', 'MyRole') called at test.pl line 26
    MyClass::BUILD('Moose::Meta::Class::__ANON__::SERIAL::1=HASH(0x55616408ff98)', 'HASH(0x5561630e81e0)') called at constructor MyClass::new (defined at test.pl line 29) line 28
    MyClass::new('MyClass') called at test.pl line 33

but, If change Moose to Mouse

perl test.pl
Use of uninitialized value in printf at test.pl line 35.
name: 

Even though we can use Meta-constructor or MouseX::Traits like below(AFAIK, overriding new() is not good way), we may need to consider this situation IMHO :)

package MyRole;

use Mouse::Role;

has 'name' =>
(
    is       => 'ro',
    isa      => 'Str',
    required => 1
);

no Mouse::Role;

package MyClass;

use Mouse;

# Role consuming
with 'MouseX::Traits';

around 'new' => sub
{
    my $orig = shift;
    my $self = shift;

    $self->with_traits('MyRole')->$orig(@_);
};

__PACKAGE__->meta->make_immutable(inline_constructor => 0);

package main;

my $obj = MyClass->new();

printf "name: %s\n", $obj->name;

1;
Attribute (name) is required at test.pl line 26.
    MyClass::__ANON__(CODE(0x5575a6d87568), "MyClass") called at /home/potatogim/.perl5/perlbrew/libs/perl-5.26.1@mop/lib/perl5/x86_64-linux-thread-multi/Mouse/Meta/Class.pm line 391
    Mouse::Meta::Class::__ANON__("MyClass") called at /home/potatogim/.perl5/perlbrew/libs/perl-5.26.1@mop/lib/perl5/x86_64-linux-thread-multi/Mouse/Meta/Class.pm line 345
    MyClass::new("MyClass") called at test.pl line 33
sergeykolychev commented 6 years ago

@potatogim pretty interesting usage, do you just want full parity with Moose in this case or you have a need in your application to apply roles on objects ?

sergeykolychev commented 6 years ago

Hi @potatogim, I coded a fix, https://github.com/gfx/p5-Mouse/pull/89 but not really sure if the issue warrants to be fixed and important. If the maintainers decide that it's important then probably it'll be merged, we'll see. Thanks.

potatogim commented 6 years ago

@sergeykolychev : It is the latter :)