tags:

views:

353

answers:

3

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?

+2  A: 

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.

Ether
Thanks, I looked through the docs, but apparently something this obvious was just skipped by my eyes :)
mpeters
+14  A: 

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.

hdp
The docs for `auto_deref` (in Moose git) make this clearer now.
hdp
+5  A: 

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.

Adam Bellaire