2010-11-16 2 views
1

У меня есть атрибут, который я хочу установить на основе других атрибутов класса. Я действительно хочу дефолт по атрибуту, который получает копию класса $self, а не мета для атрибута. Я хочу сделать что-то подобное в своем классе:Использование Moose, как установить значение атрибута атрибута 'ro' во время выполнения?

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

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

ответ

1

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

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

помнить также, что по умолчанию должно быть завернуто в coderef, если они сами ссылки: $some_value = sub { $instance };


на самом деле, это не будет работать - «по умолчанию» только для чтения. Вместо того, чтобы возиться с СС на таком низком уровне, я настоятельно призываю вас пересмотреть свой дизайн - например, сохраните свой «по умолчанию» в другом атрибуте и напишите дефолт по умолчанию, который делегирован ему:

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 }, 
); 
+0

Мне не повезло с этой предпосылкой. Возможно ли, что ['-> default' только для чтения] (http://search.cpan.org/~drolsky/Class-MOP-1.11/lib/Class/MOP/Attribute.pm#Informational) –

+0

@Evan: правильный , doh! отредактированный ответ. – Ether

+0

Правильно, но это не объясняет основополагающий вопрос. Что делать, если 'default' должен получить доступ к' $ self' (классу) 'shift', нет объекта, созданного из класса, который использует этот атрибут. Это некоторая неясная мета для атрибута. –

Смежные вопросы