如何使 Moose 构造函数在传递未声明的属性时死亡? [英] How to make the Moose constructor die on being passed an undeclared attribute?
问题描述
Moose 默认非常宽容.您可以拥有一个名为 Cucumber
的类,并将未声明的属性(如 wheels
)传递给构造函数.默认情况下,Moose 不会对此抱怨.但是我可能更喜欢 Moose 而不是 die
而不是接受未声明的属性.我怎样才能做到这一点?我似乎记得读过它是可能的,但在文档中找不到它说的地方.
Moose is very tolerant by default. You can have a class named Cucumber
and pass an undeclared attribute (like wheels
) to the constructor. Moose won't complain about that by default. But I might prefer Moose to rather die
than accept undeclared attributes. How can I achieve that? I seem to remember having read it is possible but cannot find the place where it says so in the docs.
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;
好的,这是说明解决方案的更新测试:
Okay, here's the updated test illustrating the solution:
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;
推荐答案
只需使用 MooseX::类中的 StrictConstructor ;这是一个元类特征,已经完全符合您的要求.
Just use MooseX::StrictConstructor in your class; it's a metaclass trait that already does exactly what you want.
这篇关于如何使 Moose 构造函数在传递未声明的属性时死亡?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!