oop beginner

How to use required attributes in Perl Moo and Moose?

Question

How to use required attributes in Perl Moo and Moose?

In Perl, both Moo and Moose provide convenient ways to declare required attributes—attributes that must be provided at object construction time. The key is setting required => 1 in the has attribute declaration. This enforces that the attribute cannot be omitted when calling new().

This example demonstrates how to use a required attribute in Moo. It defines a simple Person class with a required name attribute. The code shows what happens if you try creating a Person without a name (it throws an error) and successfully creates one when the attribute is provided.

Key Perl Concepts Used

  • has: Declares attributes in Moo/Moose, with options like is (read/write) and required.
  • Sigils: $ for scalars, used in method calls like $person->name.
  • eval: Used for catching runtime errors (like missing required attributes).
  • Package scoping: Defining a class inside a package block.
  • TMTOWTDI ("There's More Than One Way To Do It"): Moo and Moose have similar but independently implemented interfaces.

Common Pitfalls

  • Marking an attribute as required but also providing a default is usually pointless—defaults mean the attribute will never be missing.
  • For Moo and Moose to work, their respective modules must be installed (but here we demonstrate just Moo as it’s lightweight and commonly available).
  • Defining multiple packages or classes in a single script requires care with scoping and package declarations.
use strict;
use warnings;

{
    package Person;
    use Moo;

    # Declare a required 'name' attribute, read-only
    has 'name' => (
        is       => 'ro',
        required => 1,
    );

    sub greet {
        my $self = shift;
        print "Hello, my name is " . $self->name . "!\n";
    }
}

# Demonstrate usage and error trapping

# Trying to create without required attribute 'name' will fail
eval {
    my $person = Person->new();  # Missing required attribute
};
if ($@) {
    print "Error caught as expected: missing required attribute 'name'.\n";
}

# Creating object with required attribute succeeds
my $person = Person->new(name => "Alice");
$person->greet;

This example defines a Person class with a required attribute name. Attempting to instantiate Person->new() without name dies with an error, as caught by the eval. Providing name => "Alice" creates the object successfully, and calling greet prints the welcome message.

Summary: Use has 'attr' => (is => 'ro', required => 1) in both Moo and Moose to declare required attributes that enforce constructor parameters, improving robustness and clarity of your object interface.

Verified Code

Executed in a sandbox to capture real output. • v5.34.1 • 36ms

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
Error caught as expected: missing required attribute 'name'.
Hello, my name is Alice!
STDERR
(empty)

Was this helpful?

Related Questions