Вот загадка. Я использую Moose::Role в качестве интерфейса, где конкретные классы должны реализовать необходимые построители атрибутов, определенные ролью. Роль также определяет некоторые методы, которые выполняют логику над атрибутами. Вот уменьшенная версия того, что я пытаюсь сделать.
package Parent;
use Moose::Role;
requires '_build_permission_level';
has 'permission_level' => (
is => 'ro',
isa => Int,
lazy_build => 1,
);
use constant {
LEVEL1 = 1,
LEVEL2 = 2,
LEVEL3 = 3,
};
sub can_do_action {
my $self = shift;
return $self->permission_level() >= LEVEL2;
}
package Child;
use Moose;
with 'Parent';
sub _build_permission_level { return Parent->LEVEL3; }
Очевидно, у меня много дочерних классов с разными уровнями разрешений. Теперь это работает, за исключением того, что это ужасно неэффективно. Все дочерние экземпляры всегда будут иметь один и тот же уровень разрешений, но мне нужно создать его экземпляр только для того, чтобы спросить, может ли он выполнить действие. Запустив это массово 10 000 раз, вы получите картину.
Поэтому вместо этого я хотел бы сделать уровень разрешения атрибутом класса. Решает проблему эффективности по-лосячьи. Обратите внимание, что Permission_level больше не требует $self.
package Parent;
use Moose::Role;
use MooseX::ClassAttribute;
requires '_build_permission_level';
class_has 'permission_level' => (
is => 'ro',
isa => Int,
builder => '_build_permission_level',
);
use constant {
LEVEL1 = 1,
LEVEL2 = 2,
LEVEL3 = 3,
};
sub can_do_action {
return permission_level() >= LEVEL2;
}
package Child;
use Moose;
with 'Parent';
sub _build_permission_level { return Parent->LEVEL3; }
Это умирает с неопределенной ошибкой подпрограммы, не может найти Parent::permission_level. Таким образом, родитель ничего не знает об уровне разрешения. Действительно? Я смущен тем, как он не может получить доступ к своему собственному атрибуту класса. Я должен упустить что-то очень простое. Но, что еще более важно, как я должен заставить Родителя обеспечивать логику для атрибута класса, который предоставляет Ребенок?