NAME
Module::Patch - Patch package with a set of patches
VERSION
version 0.10
SYNOPSIS
To use Module::Patch directly:
# patching DBI modules so that
use Module::Patch qw(patch_package);
use Log::Any '$log';
patch_package(['DBI', 'DBI::st', 'DBI::db'], [
{action=>'wrap', mod_version=>':all', sub_name=>':public', code=>sub {
my $ctx = shift;
my $orig_sub = shift;
$log->tracef("Entering %s(%s) ...", $ctx->{orig_name}, \@_);
my $res;
if (wantarray) { $res=[$orig_sub->(@_)] } else { $res=$orig_sub->(@_) }
$log->tracef("Returned from %s", $ctx->{orig_name});
if (wantarray) { return @$res } else { return $res }
}},
]);
To create a patch module by subclassing Module::Patch:
# in your patch module
package Some::Module::patch::your_category;
use parent qw(Module::Patch);
sub patch_data {
return {
v => 2,
patches => [...], # $patches_spec
config => { # per-patch-module config
a => {
default => 1,
},
b => {},
c => {
default => 3,
},
},
};
}
1;
# using your patch module
use Some::Module::patch::your_category
-force => 1, # optional, force patch even if target version does not match
-config => {a=>10, b=>20}, # optional, set config value
;
# accessing per-patch-module config data
print $Some::Module::patch::your_category::config->{a}; # 10
print $Some::Module::patch::your_category::config->{c}; # 3, default value
# unpatch, restore original subroutines
no Some::Module::patch::your_category;
DESCRIPTION
Module::Patch is basically a convenient way to define and bundle a set of patches. Actual patching is done by the nice Alt::Monkey::Patch::SHARYANTO, which provides lexically scoped patching.
There are two ways to use this module:
subclass it
This is used for convenient bundling of patches. You create a patch module (a module that monkey-patches other module by adding/replacing/wrapping/deleting subroutines of target module) by subclassing Module::Patch and providing the patches_spec in patch_data() method.
Patch module should be named Some::Module::patch::your_category. For example, HTTP::Daemon::patch::ipv6.
require/import it directly
Module::Patch provides patch_package which is the actual routine to do the patching.
FUNCTIONS
import()
If imported directly, will export @exports as arguments and export requested symbols.
If imported from subclass, will take %opts as arguments and run patch_package() on caller package. %opts include:
-load_target => BOOL (default 1)
Load target modules. Set to 0 if package is already defined in other files and cannot be require()-ed.
-force => BOOL
Will be passed to patch_package's \%opts.
patch_package($package, $patches_spec, \%opts)
Patch target package $package
with a set of patches.
$patches_spec
is an arrayref containing a series of patch specification. Patch specification is a hashref containing these keys: action
(string, required; either 'wrap', 'add', 'replace', 'add_or_replace', 'delete'), mod_version
(string/regex or array of string/regex, can be ':all' to mean all versions; optional; defaults to ':all'). sub_name
(string/regex or array of string/regex, subroutine(s) to patch, can be ':all' to mean all subroutine, ':public' to mean all public subroutines [those not prefixed by _
], ':private' to mean all private), code
(coderef, not required if action
is 'delete').
Die if there is conflict with other patch modules (patchsets), for example if target module has been patched 'delete' and another patch wants to 'wrap' it.
NOTE: conflict checking with other patchsets not yet implemented.
Known options:
force => BOOL (default 0)
Force patching even if target module version does not match. The default is to warn and skip patching.
SEE ALSO
Pod::Weaver::Plugin::ModulePatch
Some examples of patch modules that use Module::Patch by subclassing it: Net::HTTP::Methods::patch::log_request, LWP::UserAgent::patch::https_hard_timeout.
Some examples of modules that use Module::Patch directly: Log::Any::For::Class.
AUTHOR
Steven Haryanto <stevenharyanto@gmail.com>
COPYRIGHT AND LICENSE
This software is copyright (c) 2012 by Steven Haryanto.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.