A neat way to do it would be to use roles. Say, for example, you want to monkey-patch "Example::Module". Then you'd publish your patch like this:
# 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 Ex
+ample::Module
...;
return $result;
};
1;
With a patch like that, people have two ways of using it. They can use it selectively:
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!!!
Or they can use it everywhere:
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!
Note that you're not uploading any modules or packages named Example::Module. So there shouldn't be any versioning/permissions issues with your upload.
Above code is untested, but should work.
|