use Class::Trait 'LifeGuard';
use Class::Trait 'Dog' => { explicit => 'swim' };
####
use Class::Trait (
'Trait::LifeGuard',
'Trait::Dog' => { explicit => 'swim' }
);
####
Class::Trait->promise('doggie_treat');
Class::Trait->assemble; # this flattens the traits into this class
sub AUTOLOAD {
# we'll make &doggie_treat, if needed
}
####
*{"${using_pkg}::$trait_method_name"} = \&{"${trait_pkg}::$trait_method_name"}
####
package Person;
use Class::Trait (
'Trait::LifeGuard',
'Trait::Dog' => { explicit => 'swim' }
);
sub doggie_treat {
my ($self) = @_;
return "Snausages,.. yummmm";
}
1;
####
package Trait::LifeGuard;
# make it inherit from some
# kind of base Trait object
use base 'Class::Trait::TraitBase';
sub swim {
my ($self, $target) = @_;
# would probably want to pass on any
# arguments here
return Trait::LifeGuard::_swim($self, $target);
}
# i am fleshing this out a bit to show
# how if $self->swim was actually
# the Trait::Dog implementation it
# would still work
sub save_drowning_swimmer {
my ($self, $swimmer) = @_;
my $shore = $self->station()->location();
$self->swim($swimmer->location());
$self->grab($swimmer);
$self->swim($shore);
}
# i used these two methods, so lets
# define them here anyway
sub grab {}
sub station {}
1;
package Trait::Dog;
# make it inherit from some
# kind of base Trait object
use base 'Class::Trait::TraitBase';
# make this into a variable of some
# kind, kind of like @EXPORT maybe?
my @EXPECTS = ('doggie_treat');
sub swim {
my ($self, $target) = @_;
# since we know that the 'swim' method is now
# a valid method in our $self object, we can call
# 'doggie_treat' on $self with confidence since all
# this will have been checked at compile time
Trait::Dog::_eat($self->doggie_treat());
# swim to $target
# passing on any arguments here
# that might be nessecary ...
Trait::Dog::_swim($self, $target);
}
sub _eat {
# this must be called via a fully qualified name because private
# methods are not flattened into the primary class
}
1;