oop intermediate

How to use Moose type constraints with Int, Str, and ArrayRef?

Question

How to use Moose type constraints with Int, Str, and ArrayRef?

Moose provides a powerful and flexible type constraint system to enforce attribute data types such as Int, Str, and ArrayRef. These type constraints help catch bugs early by validating attribute values during object construction and modification, which leads to more robust code.

Using Moose Type Constraints: Int, Str, and ArrayRef

Attributes are declared with the has keyword, specifying an isa option to constrain the type. Moose comes with built-in types including:

  • Int: Validates that the value is an integer scalar.
  • Str: Validates that the value is a string scalar.
  • ArrayRef: Validates that the value is a reference to an array.

You can also refine container types, for example, ArrayRef[Str] ensures all elements are strings (note this requires Moose 2.0+).

Perl-Specific Concepts Highlighted

  • Sigils: The $, @, and % sigils denote scalars, arrays, and hashes respectively. Moose attributes are accessed via methods (no sigils when calling, e.g. $obj->attr).
  • Context: Moose type constraints validate values at assignment time (scalar context). If invalid, Moose throws a runtime exception.
  • TMTOWTDI: Moose embraces Perl’s philosophy “There’s More Than One Way To Do It” by allowing flexible type declarations and attribute options.

Runnable Example

The following complete script defines an Employee class with typed attributes id, name, and skills, then creates an instance and prints information. No external dependencies or file/network access are required.

use strict;
use warnings;
use feature 'say';
use Moose;

package Employee {
    use Moose;

    has 'id' => (
        is       => 'ro',
        isa      => 'Int',        # Must be an integer
        required => 1,
    );

    has 'name' => (
        is       => 'rw',
        isa      => 'Str',        # Must be a string
        required => 1,
    );

    has 'skills' => (
        is      => 'rw',
        isa     => 'ArrayRef[Str]',  # ArrayRef of strings
        default => sub { [] },
    );
}

package main;

# Create a valid Employee object
my $emp = Employee->new(
    id     => 123,
    name   => 'John Doe',
    skills => ['Perl', 'Moose', 'OOP'],
);

say "Employee ID: ", $emp->id;
say "Name: ", $emp->name;
say "Skills: ", join(', ', @{ $emp->skills });

# Update the name attribute
$emp->name('John Q. Public');
say "Updated Name: ", $emp->name;

# Uncommenting the line below will cause a runtime error because 'abc' is not an Int:
# my $bad_emp = Employee->new(id => 'abc', name => 'Invalid');

# Uncommenting below causes type constraint failure on skills (non-string inside array):
# $emp->skills([123]);

Common Pitfalls & Tips

  • Type Constraint Failures: Moose throws detailed exceptions if you assign invalid values; use eval or Try::Tiny to catch them if needed.
  • Coercions: Built-in types like Int and Str do not have coercions enabled by default, so you must pass correct types or enable custom coercions.
  • Version Requirements: Container types like ArrayRef[Str] need Moose 2.0+.
  • Attribute Access: Use method calls without sigils (e.g. $obj->name), not direct hash access.
  • Required Attributes: Specifying required => 1 ensures Moose enforces the presence of attributes during instantiation.

Using Moose type constraints is a clean way to add data validation and improve maintainability, leveraging Perl’s expressive object system.

Verified Code

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

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
Employee ID: 123
Name: John Doe
Skills: Perl, Moose, OOP
Updated Name: John Q. Public
STDERR
(empty)

Was this helpful?

Related Questions