Search code examples
perlmoose

How can I acces read-only attributes of Moose objects?


I'm an absolute newbie to Moose and so far I have read Moose and most of the Cookbook.

There a few things I don't get. I created the following package:

package MyRange;

use Moose;
use namespace::autoclean;

has [ 'start', 'end' ] => (
    is       => 'ro',
    isa      => 'Int',
    required => 1,
);

__PACKAGE__->meta->make_immutable;

1;

Then:

use MyRange;    
my $br = MyRange->new(
    start                => 100,
    end                  => 180
);

Now I can access my fields using e.g. $br->{start}, but I can also modify them (although they are "read only") using e.g. $br->{start}=5000. I can also add new keys like $br->{xxx}=111.

Am I missing anything? Isn't the object protected in some way? What's the meaning of ro?


Solution

  • When you said is => 'ro' you told Moose to create read-only accessors for you, that is, a reader method. You call that as

    $br->start;
    

    or

    $br->end;
    

    Setting the attributes using those methods will result in an exception:

    $br->start(42);
    

    If you had used is => 'rw', then the above would work and update the attribute's value.

    What you're doing is direct hash access on the object, which violates encapsulation and shouldn't ever be necessary when using Moose.

    The Moose manual, i.e. all the documents under the Moose::Manual namespace explain that in detail. A good starting point for questions like this is probably Moose::Manual::Attributes.