8

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?

3 Answers 3

19

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.

Sign up to request clarification or add additional context in comments.

1 Comment

The docs for auto_deref (in Moose git) make this clearer now.
6

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.

Comments

3

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.

1 Comment

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.