Используя Moose, как мне установить значение атрибута ro в атрибуте runtime?
У меня есть атрибут атрибута, который я хочу установить на основе других атрибутов класса. Я действительно хочу по умолчанию для Attribute Trait, который получает копию класса $self
а не мета для атрибута. Я хочу сделать что-то подобное в своем классе:
after 'BUILD' => sub {
my $self = shift;
$self->meta->get_attribute('id')->column_name( $self->_unique_key_name );
};
Но я хочу сохранить свой атрибут RO? Это возможно. Я знаю, что MOP позволяет установить значение атрибута класса, но я не могу понять, как установить атрибут в метаатрибуте.
1 ответ
Это звучит как очень странный дизайн (зачем метаклассу нужен экземпляр класса, который он описывает?) - но вы можете сделать это достаточно легко, используя метакласс метакласса (помните, что метаслассы Moose загружаются с помощью MOP сам):
$self->meta->meta->get_attribute("foo")->default($some_value);
Также помните, что значения по умолчанию должны быть помещены в coderef, если они сами являются ссылками: $some_value = sub { $instance };
На самом деле, это не будет работать - "по умолчанию" только для чтения. Вместо того, чтобы возиться с MOP на таком низком уровне, я бы посоветовал вам пересмотреть свой дизайн - например, сохранить свой "default" в другом атрибуте и написать подпрограмму по умолчанию, делегированную ему:
package MyApp::Meta::Attribute::Trait::Foo;
# set at runtime, when we have an instance to store here
has _default_of_foo => (
is => 'rw', isa => 'Object',
);
has foo => (
is => 'ro', isa => 'Object',
lazy => 1,
default => sub { shift->_default_of_foo },
);