Как заставить конструктор Moose умереть при получении необъявленного атрибута? - PullRequest
9 голосов
/ 28 апреля 2011

Лоси очень терпимы по умолчанию.Вы можете иметь класс с именем Cucumber и передать необъявленный атрибут (например, wheels) в конструктор.Лось не будет жаловаться на это по умолчанию.Но я мог бы предпочесть лося скорее die, чем принимать необъявленные атрибуты.Как я могу этого достичь?Кажется, я помню, что прочитал, что это возможно, но не могу найти место, где говорится в документах.

package Gurke;
use Moose;
has color => is => 'rw', default => 'green';
no Moose;
__PACKAGE__->meta->make_immutable;

package main; # small test for the above package
use strict;
use warnings;
use Test::More;
use Test::Exception;
my $gu = Gurke->new( color => 'yellow' );
ok $gu->color, 'green';
if ( 1 ) {
    my $g2 = Gurke->new( wheels => 55 );
    ok ! exists $g2->{wheels}, 'Gurke has not accepted wheels :-)';
    # But the caller might not be aware of such obstinate behaviour.
    diag explain $g2;
}
else {
    # This might be preferable:
    dies_ok { Gurke->new( wheels => 55 ) } q(Gurken can't have wheels.);
}
done_testing;

Хорошо, вот обновленный тест, иллюстрирующий решение:

package Gurke;
use Moose;
# By default, the constructor is liberal.
has color => is => 'rw', default => 'green';
no Moose;
__PACKAGE__->meta->make_immutable;

package Tomate;
use Moose;
# Have the Moose constructor die on being passed undeclared attributes:
use MooseX::StrictConstructor;
has color => is => 'rw', default => 'red';
no Moose;
__PACKAGE__->meta->make_immutable;

package main; # small test for the above packages
use strict;
use warnings;
use Test::More;
use Test::Exception;

my $gu = Gurke->new( color => 'yellow' );
ok $gu->color, 'green';
my $g2 = Gurke->new( wheels => 55 );
ok ! exists $g2->{wheels}, 'Gurke has not accepted wheels :-)';
diag 'But the caller might not be aware of such obstinate behaviour.';
diag explain $g2;

diag q(Now let's see the strict constructor in action.);
my $to = Tomate->new( color => 'blue' );
diag explain $to;
dies_ok { Tomate->new( wheels => 55 ) } q(Tomaten can't have wheels.);

done_testing;

1 Ответ

15 голосов
/ 28 апреля 2011

Просто используйте MooseX :: StrictConstructor в своем классе; это черта метакласса, которая уже делает именно то, что вы хотите.

...