2009-12-07 4 views
8

У меня есть класс Moose с атрибутом, который является ArrayRef (только для чтения) и управляется внутри объекта. Но когда кто-то вызывает метод доступа, я хочу, чтобы он возвращал массив (или список), а не ссылку. Мало того, что это сократит количество разыменований, которые должен выполнять пользователь класса, но это будет означать, что они не могут случайно вмешаться с тем же реф, что и мой объект.Атрибут Moose ArrayRef, возвращаемый как массив

Итак, каков наилучший способ сделать это? Какое-то принуждение?

ответ

17

Использовать Moose::Meta::Attribute::Native::Trait::Array и делегировать, например.

handles => { my_array => 'elements' } 

(через Ду на #moose)

auto_deref имеет нежелательное поведение еще возвращает ссылку, если вы звоните аксессор в скалярном контексте.

+2

Теперь документы для 'auto_deref' (в Moose git) сделают это яснее. – hdp

3

Используйте auto_deref вариант:

has my_field => (
    is => 'ro', isa => 'ArrayRef[Str]', 
    auto_deref => 1, 
    # rest of options... 
); 

Обратите внимание, что иногда вы не получите массив обратно при использовании метода чтения, в зависимости от скалярного или списка контекста выражения. Некоторое время назад я столкнулся с ситуацией, когда мне приходилось явно приводить контекст массива к выражению, чтобы заставить разыменоваться работать. Я добавлю пример, если найду его.

+1

Спасибо, я просмотрел документы, но, видимо, что-то такое очевидное было просто пропущено моими глазами :) – mpeters

6

В то время как вы можете использовать auto-deref, Moose::Manual::BestPractices говорит, что это не лучший способ сделать это, и вам следует вместо этого использовать Moose::Meta::Attribute::Native для выполнения этой функции.