由角色提供的编译时健全性检查

时间:2015-02-03 17:55:07

标签: perl moose

我有一个拒绝加载的模块,除非满足编译时健全性检查。像这样:

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“'的东西 - 除了它不仅要验证方法是否存在,还要执行它并检查返回值。

1 个答案:

答案 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.