How to use MooseX::StrictConstructor to catch typos in Perl?
Question
How to use MooseX::StrictConstructor to catch typos in Perl?
MooseX::StrictConstructor is a Moose extension that helps catch bugs related to misspelled attributes during object construction in Perl's Moose-based classes. By default, Moose allows extra constructor arguments that do not correspond to declared attributes, which often results in silent typos or unexpected behavior. MooseX::StrictConstructor enforces strict checking and causes the constructor to die if unknown attributes are passed, helping you catch typos early.
What is MooseX::StrictConstructor?
MooseX::StrictConstructor is a Moose role that modifies the constructor behavior so it only accepts valid attributes declared in your class. If you try to construct an object with an attribute name that doesn’t exist, the constructor throws an exception immediately.
This fits nicely with Perl's "There's More Than One Way To Do It" (TMTOWTDI) philosophy, giving you an option to enforce stricter validation when working with Moose objects.
How to use MooseX::StrictConstructor
- Install the module from CPAN if you don’t have it (
cpanm MooseX::StrictConstructororcpan MooseX::StrictConstructor). - In your Moose class, use the role
MooseX::StrictConstructor. - Define your attributes as usual.
- When creating an object, any typo in attribute names will cause the constructor to die with an error.
Example: Catching typos with MooseX::StrictConstructor
use strict;
use warnings;
{
package Person;
use Moose;
use MooseX::StrictConstructor;
has 'name' => (
is => 'ro',
isa => 'Str',
required => 1,
);
has 'age' => (
is => 'ro',
isa => 'Int',
required => 1,
);
}
# Correct usage
my $person = Person->new(
name => 'Alice',
age => 30,
);
print "Created person: ", $person->name, ", age ", $person->age, "\n";
# Typo in attribute name will cause error because of MooseX::StrictConstructor
eval {
my $person2 = Person->new(
name => 'Bob',
agee => 25, # typo here: should be 'age'
);
};
if ($@) {
print "Error caught: $@";
}
How It Works
- The class
PersonconsumesMooseX::StrictConstructor. - The constructor
newstrictly expects onlynameandageas keys. - When a typo like
ageeis present, the constructor dies with an error such asFound unknown attribute(s) passed to the constructor: agee. - The
evalblock demonstrates how you can catch this error and respond accordingly.
Version Notes and Pitfalls
MooseX::StrictConstructorworks with Moose versions from around 2.00+ onwards (Perl 5.8+ generally).- If you override
BUILDARGSin your class, be careful to supportMooseX::StrictConstructorexpectations to avoid false positives. - This extension only affects the
newconstructor, so other ways of object construction (likeclone) are not checked. - Strict constructor checking improves code robustness, but for very large attribute sets, you might want to benchmark since the checks add a small overhead.
Summary
By using MooseX::StrictConstructor, you enforce strict attribute validation at object construction, catching misspelled or unexpected attributes early. This eliminates a common source of bugs in Moose-based object-oriented Perl code and improves maintainability, especially on large projects.
Verified Code
Executed in a sandbox to capture real output. • v5.34.1 • 184ms
Created person: Alice, age 30
Error caught: Attribute (age) is required at /System/Library/Perl/Extras/5.34/darwin-thread-multi-2level/Moose/Meta/Class.pm line 275
Moose::Meta::Class::new_object('Moose::Meta::Class::__ANON__::SERIAL::1=HASH(0x12da20270)', 'HASH(0x138a9fba8)') called at /System/Library/Perl/Extras/5.34/MooseX/StrictConstructor/Trait/Class.pm line 17
Class::MOP::Class:::around('CODE(0x12e9713a8)', 'Moose::Meta::Class::__ANON__::SERIAL::1=HASH(0x12da20270)', 'HASH(0x138a9fba8)') called at /System/Library/Perl/Extras/5.34/darwin-thread-multi-2level/Class/MOP/Method/Wrapped.pm line 164
Moose::Meta::Class::__ANON__::SERIAL::1::_wrapped_new_object('Moose::Meta::Class::__ANON__::SERIAL::1=HASH(0x12da20270)', 'HASH(0x138a9fba8)') called at /System/Library/Perl/Extras/5.34/darwin-thread-multi-2level/Class/MOP/Method/Wrapped.pm line 95
Moose::Meta::Class::__ANON__::SERIAL::1::new_object('Moose::Meta::Class::__ANON__::SERIAL::1=HASH(0x12da20270)', 'HASH(0x138a9fba8)') called at /System/Library/Perl/Extras/5.34/darwin-thread-multi-2level/Moose/Object.pm line 24
Moose::Object::new('Person', 'name', 'Bob', 'agee', 25) called at - line 32
eval {...} at - line 31
(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 convert a Perl Moo class to Moose?
- How to use Moo lazy_build for attribute defaults in Perl?