Modern objects with Moo
| has | |
| Required, default, lazy | |
| extends | |
| When to use Moo |
has
Moo turns a class into a declaration. Each attribute is one has line with a name, a read mode and optional checks, and the constructor plus accessors are generated for you.
package User;
use Moo;
has name => (is => 'ro', required => 1);
has age => (is => 'rw', default => sub { 0 });
1;
ro means read-only, rw means the accessor also sets. The new method appears automatically, so the caller writes User->new(name => "Ada").
Required, default, lazy
Declarations can check values and compute them on first use. The isa check rejects a wrong type where the bug happens instead of three calls later.
use Types::Standard qw(Int Str);
has email => (is => 'ro', isa => Str, required => 1);
has score => (is => 'rw', isa => Int, default => 0);
Lazy attributes are built on first read and cached afterwards, which is perfect for expensive objects such as a database connection. The builder sub holds the code that creates it.
has dbh => (is => 'ro', lazy => 1, builder => sub {
my ($self) = @_;
return DBI->connect($self->dsn);
});
extends
Inheritance is one declaration. The child sees the parent attributes and may add methods or override them; call super to run the parent version first.
package Admin;
use Moo;
extends 'User';
has role => (is => 'ro', default => 'admin');
sub describe {
my ($self) = @_;
return $self->name . " (" . $self->role . ")";
}
1;
Moo is small and fast because it avoids a meta-object protocol. Moose is the older, heavier system with roles, type coercions and introspection; Moo classes can be upgraded to Moose later without changing the callers.
When to use Moo
Use Moo when a class is mostly data with a few methods, which describes most application code. Stay with plain bless when the class is tiny, and reach for Moose when you need roles or a plugin ecosystem.
Either way, install the module first: cpanm Moo. Types::Standard comes with Type::Tiny and is the companion for isa checks.
Next: Testing with Test::More
Article author: Arthur Isaev