How to convert a Perl Moo class to Moose?
Question
How to convert a Perl Moo class to Moose?
Converting a Perl Moo class to Moose is a common task when you want to leverage Moose's richer feature set, such as method modifiers, type constraints, or metaclasses, while having initially developed your code using the lightweight Moo framework. Since Moo was designed to be mostly compatible with Moose but without its heavier runtime, the migration is often straightforward.
Key Differences Between Moo and Moose
- Base class: Moo uses
use Moo;vs Moose usesuse Moose;. - Attributes: Mostly similar syntax, but Moose supports richer attribute options (e.g.,
traits,isatype constraints, coercions). - Method modifiers: Both support
before,after, andaround, but Moose’s are more feature-rich. - Immutable: Moose recommends calling
__PACKAGE__->meta->make_immutablefor performance. Moo has no equivalent. - Dependencies: Moose has many more dependencies and a heavier runtime.
Basic Conversion Steps
- Change
use Moo;touse Moose;. - Adjust attributes if needed to add Moose-only features (e.g.,
isatype constraints). - Add
__PACKAGE__->meta->make_immutable;at the end of the package to improve performance. - Review your method modifiers and extensions; Moose allows more flexibility (e.g., method handles, method aliases).
- Test thoroughly, because some Moo features default differently (e.g.,
requiredattribute behavior).
Sample Conversion
Here’s a runnable example demonstrating a simple Moo class converted to Moose.
use strict;
use warnings;
# Original Moo class
package PersonMoo;
use Moo;
has 'name' => (
is => 'ro',
required => 1,
);
has 'age' => (
is => 'rw',
default => sub { 20 },
);
sub greet {
my $self = shift;
return "Hello, my name is " . $self->name . " and I am " . $self->age . " years old.";
}
1;
# Converted Moose class
package PersonMoose;
use Moose;
has 'name' => (
is => 'ro',
isa => 'Str',
required => 1,
);
has 'age' => (
is => 'rw',
isa => 'Int',
default => sub { 20 },
);
sub greet {
my $self = shift;
return "Hello, my name is " . $self->name . " and I am " . $self->age . " years old.";
}
__PACKAGE__->meta->make_immutable;
1;
# Script to test both
package main;
my $m_person = PersonMoo->new(name => 'Alice');
print $m_person->greet () . "\n";
my $ms_person = PersonMoose->new(name => 'Bob', age => 35);
print $ms_person->greet () . "\n";
Explanation
MooandMoosesyntax forhasis very similar; the main difference is that with Moose you can specify type constraints withisa(e.g.,Str,Int).required => 1works the same in both, signaling the attribute must be passed to the constructor.- The
defaultcoderef syntax is identical. - Moose classes should call
__PACKAGE__->meta->make_immutablefor improved speed and reduced memory usage. - The rest of the code (methods like
greet) remains unchanged.
Common Gotchas
- Required attributes: Moo’s
requiredis less strict if lazily built attributes are involved; Moose enforces this more properly. - Build methods: Moo does not autogenerate
BUILDorDEMOLISHmethods; Moose expects and calls them during construction and destruction. - Type constraints: You’ll want to add
isadeclarations explicitly in Moose — this is a great time to add type safety. - Immutable: Forgetting
make_immutablein Moose will cause slower object creation. - Dependencies: Moose is heavier; consider whether you need the extra features before converting.
In summary, converting a Moo class to Moose involves changing the import, adding type constraints, and finishing with make_immutable. Because Moo was designed to be mostly compatible with Moose, your existing code will often require minimal changes.
Verified Code
Executed in a sandbox to capture real output. • v5.34.1 • 245ms
Hello, my name is Alice and I am 20 years old.
Hello, my name is Bob and I am 35 years old.
(empty)Was this helpful?
Related Questions
- How to use Moose::Util::TypeConstraints for custom types?
- How to implement method delegation in Perl Moo?
- How to use Type::Tiny with Moo for strict typing in Perl?
- How to use required attributes in Perl Moo and Moose?
- How to use Moo lazy_build for attribute defaults in Perl?
- How to implement multiple inheritance with Moose in Perl?