0

I am fairly new to Moose, and have been trying to follow the best practices. I understand that we should try to make classes immutable when we can. My question is, after object construction, can we change the value of a public attribute using a setter and still have the class be immutable?

  • 1
    As per @amon's answer, `__PACKAGE__->meta->make_immutable` makes the *class* immutable rather than making *instances* immutable. But I'll add that making instances immutable (by making attributes read-only) is usually a good idea too. Mutable instances can lead to action at a distance (if two parts of your code are holding references to the same object, one can make changes to the object, and the other will see those changes) which can lead to code which is harder to debug. Mutable instances are sometimes necessary, but when possible you should attempt to design your code to avoid them. – tobyink Apr 19 '14 at 18:30

1 Answers1

1

Yes. If a class is immutable, this only means we cannot add new attributes or new methods to the class. This allows the Moose system do do some neat optimizations.

Any instances of the class can still be mutated. In order for the instances to be immutable as well, all attributes must be readonly (is => 'ro').

Example:

package MyClass;
use Moose;

has attr => (is => 'rw'); # this attribute is read-write

__PACKAGE__->meta->make_immutable;
# after this, no new attributes can be added

Then:

my $instance = MyClass->new(attr => "foo");

say $instance->attr; # foo
$instance->attr("bar"); # here, we change the instance, but not the class
say $instance->attr; # bar
amon
  • 57,091
  • 2
  • 89
  • 149