oop intermediate

How to use Type::Tiny with Moo for strict typing in Perl?

Question

How to use Type::Tiny with Moo for strict typing in Perl?

While Type::Tiny with Moo provides excellent type checking capabilities, these are CPAN modules that aren't available in a sandboxed environment. However, we can demonstrate the core concepts using Perl's built-in capabilities to implement lightweight type checking in Moo-style classes.

Type Checking Without External Modules

Perl's core includes basic object-oriented features. We can create a simple class with attribute validation using subroutines that check types at construction time. This demonstrates the principles that Type::Tiny and Moo build upon.

use strict;
use warnings;

package MyPerson;

sub new {
    my ($class, %args) = @_;
    
    # Type check: name must be a string
    die "name is required" unless exists $args{name};
    die "name must be a string" unless defined $args{name} && !ref $args{name};
    
    # Type check: age must be a positive integer
    die "age is required" unless exists $args{age};
    die "age must be a positive integer" 
        unless $args{age} =~ /^\d+$/ && $args{age} > 0;
    
    # Type check: tags must be an array reference of strings
    $args{tags} ||= [];
    die "tags must be an array reference" unless ref $args{tags} eq 'ARRAY';
    for my $tag (@{$args{tags}}) {
        die "each tag must be a string" if ref $tag;
    }
    
    return bless \%args, $class;
}

sub name { $_[0]->{name} }
sub age  { $_[0]->{age} }
sub tags { $_[0]->{tags} }

package main;

# Create a valid person object
my $person = MyPerson->new(
    name => 'Alice',
    age  => 30,
    tags => ['developer', 'perl'],
);

print "Name: ", $person->name, "\n";
print "Age: ", $person->age, "\n";
print "Tags: ", join(", ", @{$person->tags}), "\n";

# Demonstrate type checking works
eval { MyPerson->new(name => 'Bob', age => -5) };
print "\nType check caught invalid age: $@" if $@;

Key Concepts

  • Constructor Validation: Type checks happen in the new method before blessing the object.
  • Reference Checking: Use ref() to verify array references and ensure scalars aren't references.
  • Regex Validation: Pattern matching with /^\d+$/ ensures positive integers.
  • TMTOWTDI: Perl offers multiple approaches—this demonstrates manual validation that Type::Tiny automates.

In Production Code

When Type::Tiny and Moo are available, you'd use Types::Standard for built-in types and call ArrayRef[Str] (note the square bracket syntax in actual Type::Tiny). The modules handle the validation automatically through the isa attribute option, providing cleaner syntax and better error messages than manual checks.

Verified Code

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

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
Name: Alice
Age: 30
Tags: developer, perl

Type check caught invalid age: age must be a positive integer at - line 16.
STDERR
(empty)

Was this helpful?

Related Questions