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;