# lib/Example/Module/Enhanced.pm use 5.008009; use strict; use warnings; package Example::Module::Enhanced; use constant PATCH => __PACKAGE__ . '::Trait'; use constant TARGET => 'Example::Module'; sub import { my ( $me, $arg ) = @_; 'Role::Tiny'->apply_roles_to_package( $me->TARGET, $me->PATCH ) if defined($arg) && $arg eq '-auto'; } sub patch_object { my ( $me, $obj ) = @_; 'Role::Tiny'->apply_roles_to_object( $obj, $me->PATCH ); return $obj; } # Yes, it's safe to define this second package in the same file... package Example::Module::Enhanced::Trait; use Role::Tiny; sub some_new_method { my ( $self, @args ) = @_; ... } around some_existing_method => sub { my ( $orig, $self, @args ) = @_; ...; my $result = $self->$orig( @args ); # call original method from Example::Module ...; return $result; }; 1; #### use Example::Module; use Example::Module::Enhanced; my $obj = Example::Module->new; my $obj2 = Example::Module->new; Example::Module::Enhanced->patch_object( $obj ); # Now $obj1 has your monkey patch, but $obj2 is still non-patched!!! #### use Example::Module; use Example::Module::Enhanced -auto; my $obj = Example::Module->new; my $obj2 = Example::Module->new; # All Example::Module objects are monkey-patched!