use v5.10; use strict; use warnings; { package Person; use Moo; has name => (is => 'ro', default => 'erere'); has age => (is => 'ro', default => 233); sub BUILD { my $self = shift; if ($self->age < 20) { 'Moo::Role'->apply_roles_to_object($self, 'Person::Baby'); } else { 'Moo::Role'->apply_roles_to_object($self, 'Person::Adult'); } } sub sayHello { my $self = shift; say "Hello from ", $self->name; } } { package Person::Baby; use Moo::Role; around sayHello => sub { shift; my $self = shift; say "Goo-goo, gaa-gaa from ", $self->name; }; } { package Person::Adult; use Moo::Role; } my $alice = 'Person'->new(name => 'Alice', age => 0.5); my $bob = 'Person'->new(name => 'Bob', age => 50); for my $person ($alice, $bob) { if ($person->isa('Person')) { say $person->name, " is a 'Person'!"; } if ($person->DOES('Person::Adult')) { say $person->name, " does the 'Person::Adult' role!"; } if ($person->DOES('Person::Baby')) { say $person->name, " does the 'Person::Baby' role!"; } $person->sayHello; say "----"; } say "Now let's look at the employees!"; { package Employee; use Moo; extends 'Person'; has dept => (is => 'ro', default => 'Administrative Affairs'); sub BUILD { my $self = shift; if ($self->dept eq 'IT') { 'Moo::Role'->apply_roles_to_object($self, 'Employee::IT'); } elsif ($self->dept eq 'Finance') { 'Moo::Role'->apply_roles_to_object($self, 'Employee::Finance'); } } } { package Employee::IT; use Moo::Role; sub fixComputer { my $self = shift; say "Happy to help!"; } } { package Employee::Finance; use Moo::Role; sub payOtherEmployees { my $self = shift; for my $other (@_) { next unless $other->isa('Employee'); say $self->name, " pays ", $other->name; } } } my $carol = 'Employee'->new(name => 'Carol', dept => 'IT', age => 40); my $dave = 'Employee'->new(name => 'Dave', dept => 'IT', age => 19); my $eve = 'Employee'->new(name => 'Eve', dept => 'Finance', age => 58); for my $person ($carol, $dave, $eve) { if ($person->isa('Person')) { say $person->name, " is a 'Person'!"; } if ($person->isa('Employee')) { say $person->name, " is an 'Employee'!"; } if ($person->DOES('Person::Adult')) { say $person->name, " does the 'Person::Adult' role!"; } if ($person->DOES('Person::Baby')) { say $person->name, " does the 'Person::Baby' role!"; } if ($person->DOES('Employee::IT')) { say $person->name, " does the 'Employee::IT' role!"; $person->fixComputer; } if ($person->DOES('Employee::Finance')) { say $person->name, " does the 'Employee::Finance' role!"; } $person->sayHello; say "----"; } # Were Alice and Bob employees? $eve->payOtherEmployees($alice, $bob, $carol, $dave);