Как я могу получить доступ к атрибутам моего объекта при помощи Moose? - PullRequest
4 голосов
/ 25 февраля 2011

Я хочу привести Str в объект DBIx :: Class :: Row для атрибута в моем классе Moose. Для этого мне нужно выполнить поиск в схеме DBIC, чтобы найти строку. Я хочу выдвинуть ошибку в атрибут ArrayRef, если поиск не удался.

В настоящее время я передаю схему в качестве атрибута моему классу.

При принуждении кажется, что я не могу получить доступ к объекту, поэтому я не могу нажать на атрибут errorrerereref или использовать объект схемы для выполнения моего поиска.

Альтернативой, которую я попытался, было использование «вокруг» для поиска и установки атрибута, когда он установлен, но это, конечно, не вызывается, когда значение атрибута передается через конструктор.

Возможно ли это, или у кого-то есть альтернативная реализация, чтобы сделать то, чего я хочу достичь?

1 Ответ

4 голосов
/ 25 февраля 2011

Вы можете перехватить и изменить значение, сохраняемое при передаче в конструктор с инициализатором атрибута .(Однако он запускается только тогда, когда атрибут установлен в конструкторе, а не в любое другое время.) Документацию для инициализаторов можно найти в Class :: MOP :: Attribute .

Поскольку при этом учитываются только случаи, когда атрибут задается с помощью конструктора, вам все равно необходимо отследить другие случаи, когда атрибут установлен.Это можно сделать с помощью модификатора метода, как вы сказали, но вы можете объединить два метода в один, обернутый вокруг автоматически созданного метода доступа:

has my_attr => (
    is => 'rw',
    isa => 'DBIx::Class::Row',
    initializer => 'my_attr',
);

# my_attr is the autogenerated accessor - we method-modify it to mutate the
# value being set, and catch cases where it is called as an initializer.

# called for reads, writes, and on initialization at construction time
around 'my_attr' => sub {
    my $orig = shift;
    my $self = shift;
    # value is not defined if being called as a reader
    # setter and attr are only defined if being called as an initializer
    my ($value, $setter, $attr) = @_;

    # the reader behaves normally
    return $self->$orig if not @_;

    # convert the string to the row object
    my $row = $self->convert_str_to_row_obj($value);

    # if called as an initializer, set the value and we're done
    return $setter->($row) if $setter;

    # otherwise, call the real writer with the new value
    $self->$orig($row);
};
...