我有一个拒绝加载的模块,除非满足编译时健全性检查。像这样:
package TopSecret;
use Moose;
die "Only Joe can use this!" unless $ENV{USER} eq 'joe';
1;
现在我想对多个模块应用类似的健全性检查,所以我的想法就是把它放在一个角色里。消费模块将提供一些信息来定制检查。所以它可能看起来像:
package TopSecret;
use Moose;
with 'ForAuthorizedUser';
sub authorized_user { 'joe' }
1;
问题是:如何在编译时从ForAuthorizedUser中运用TopSecret :: authorized_user()?类似于“require”authorized_user“'的东西 - 除了它不仅要验证方法是否存在,还要执行它并检查返回值。
答案 0 :(得分:1)
我认为属性覆盖在这里是合适的。您在角色中声明属性并根据需要进行标记,但不提供定义。然后,使用Role的模块可以提供该属性的值。请注意,验证通常在BUILD()
子例程中完成。
package ForAuthorizedUser;
use Moose::Role;
use Carp qw(croak); # so you can see the line it fails on
has 'authorized_user' => (
is => 'ro',
required => 1,
);
sub BUILD {
my ($self) = @_;
croak "Only Joe can use this!"
unless $self->authorized_user eq 'joe';
}
1;
现在,在使用ForAuthorizedUser的模块中,您提供了属性的定义:
package TopSecret;
use Moose;
with qw(ForAuthorizedUser);
has '+authorized_user' => (
default => 'joe',
);
__PACKAGE__->meta->make_immutable;
在一个单独的模块中,你做同样的事情,但使用不同的名字(我的):
package TopSecret2;
use Moose;
with qw(ForAuthorizedUser);
has '+authorized_user' => (
default => 'hunter',
);
__PACKAGE__->meta->make_immutable;
然后你可以这样测试:
use TopSecret;
use TopSecret2;
TopSecret->new; # lives
TopSecret2->new # croaks Only Joe can use this! at constructor TopSecret2::new (defined at Test.pm line 35) line 36.