I have a Moose class with an attribute that is an ArrayRef (read-only) and is manipulated internally by the object. But when someone calls the accessor method I want it to return an Array (or list) not a reference. Not only would this cut down on the amount of dereferencing that the user of the class has to do,开发者_运维知识库 but it will mean they can't accidentally tamper with the same ref that my object is using.
So what's the best way to do this? Some sort of coercion?
Use Moose::Meta::Attribute::Native::Trait::Array and delegation, e.g.
handles => { my_array => 'elements' }
(via doy on #moose)
auto_deref
has the undesirable behavior of still returning a reference if you call the accessor in scalar context.
While you can use auto-deref
, Moose::Manual::BestPractices says that this isn't the best way to do it, and that you should instead consider using Moose::Meta::Attribute::Native to accomplish that functionality.
Use the auto_deref option:
has my_field => (
is => 'ro', isa => 'ArrayRef[Str]',
auto_deref => 1,
# rest of options...
);
Note that sometimes you won't get an array back when using the reader method, depending on the scalar or list context of the expression. A while ago I ran into a situation where I had to explicitly bring array context to the expression in order to get the dereferencing to work.. I'll add an example if I can find it.
精彩评论