Используя Moose, как мне установить значение атрибута ro в атрибуте runtime? - PullRequest
1 голос
/ 16 ноября 2010

У меня есть черта атрибута, которую я хочу установить на основе других атрибутов класса.Я действительно хочу по умолчанию для Attribute Trait, который получает копию класса $self, а не мета для атрибута.Я хочу сделать что-то вроде этого в моем классе:

after 'BUILD' => sub {                                                     
  my $self = shift;                                                        
  $self->meta->get_attribute('id')->column_name( $self->_unique_key_name );
};  

Но я хочу сохранить свой атрибут RO?Это возможно.Я знаю, что MOP позволяет установить значение атрибута класса, но я не могу понять, как установить атрибут для мета-атрибута.

1 Ответ

1 голос
/ 16 ноября 2010

Это звучит как действительно странный дизайн (зачем метаклассу нужен экземпляр класса, который он описывает?), - но вы можете сделать это достаточно легко, используя метакласс метакласса (помните, что мета-классы Moose загружаются при загрузке).используя саму MOP):

$self->meta->meta->get_attribute("foo")->default($some_value);

Также помните, что значения по умолчанию должны быть заключены в кодовую ссылку, если они сами являются ссылками: $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 },
);
...