Using Perl and Moose, object data can be accessed in 2 ways.
$self->{attribute} or $self->attribute()
Here is a si
When using Moose, the best practice is to always use the generated accessor methods, even when inside the object's own class. Here are a few reasons:
The accessor methods may be over-ridden by a child class that does something special. Calling $self->age() assures that the correct method will be called.
There may be method modifiers, such as before or after, attached to the attribute. Accessing the hash value directly will skip these.
There may be a predicate or clearer method attached to the attribute (e.g. has_age). Messing with the hash value directly will confuse them.
Hash keys are subject to typos. If you accidentally say $self->{aeg} the bug will not be caught right away. But $self->aeg will die since the method does not exist.
Consistency is good. There's no reason to use one style in one place and another style elsewhere. It makes the code easier to understand for newbs as well.
In the specific case of a read-only attribute, here are some strategies:
Make your objects truly immutable. If you need to change a value, construct a new object which is a clone of the old one with the new value.
Use a read-only attribute to store the real age, and specify a private writer method
For example:
package Person;
use Moose;
has age => ( is => 'ro', isa => 'Int', writer => '_set_age' );
sub HAPPY_BIRTHDAY {
my $self = shift;
$self->_set_age( $self->age + 1 );
}
Update
Here's an example of how you might use a lazy builder to set one attribute based on another.
package Person;
use Moose;
has age => ( is => 'rw', isa => 'Int', lazy => 1, builder => '_build_age' );
has is_baby => ( is => 'rw', isa => 'Bool', required => 1 );
sub _build_age {
my $self = shift;
return $self->is_baby ? 1 : 52
}
The lazy builder is not called until age is accessed, so you can be sure that is_baby will be there.
Setting the hash element directly will of course skip the builder method.