package Animal; use Moo; has [qw(name gender)] => (is => 'ro'); package Pet; use Moo::Role; has [qw(treats pref)] => (is => 'ro'); sub play { sprintf "%s a %s", $_[0]->pref, @{$_[0]->treats}[rand@{$_[0]->treats}] } package Dog; use Moo; extends 'Animal'; with 'Pet'; package Cat; use Moo; extends 'Animal'; with 'Pet'; package main; my @pets = ( Dog->new( name => 'Odie', gender => 'male', pref => 'chases', treats => [qw(ball bone doll)] ), Cat->new( name => 'Garfield', gender => 'male', pref => 'eats', treats => [qw(lasagna pookie blanket)] ), ); printf "%s, being %s, %s.\n", $_->name, $_->gender, $_->play for @pets;