| Module-Replace documentation | Contained in the Module-Replace distribution. |
Module::Replace - Replace functionality in other modules
Version 0.01
use Module::Replace 'Other::Module' => qw(new);
The purpose of this module is to allow you to override functions in one module with the same-named functions in another.
This can be a global change, or a temporary change.
The reasons why you may want to do this include:
use Module::Replace 'YourFramework::Type', qw(new);
There are two types of usage: global and local replacement.
This is primarily targetted at frameworks. Here you call:
use Module::Replace 'YourFramework::Type', qw(new);
from within the derived object. This will both call use base 'YourFramework::Type'
and override new with your own. Note that access to the original new method
is still available via SUPER_new, e.g.:
sub new {
my $class = shift;
# allow re-derivations
$class = __PACKAGE__ if $class eq 'YourFramework::Type';
my $self = bless $class->SUPER_new(), $class;
# ...
}
Sometimes you only want to replace a function for a little while. For example, changing the way that File::Spec::catdir works only when calling another function. Here you call the replace and restore functions directly.
use Module::Replace;
Module::Replace::replace('File::Spec', \'File::Spec::UNIX', qw(catdir));
Some::Other::function();
Module::Replace::restore('File::Spec', \'File::Spec::UNIX');
Note that if you leave off the reference to the source package, it will assume the caller package.
This will cause catdir to work UNIX-like on all platforms for the duration
of Some::Other::function().
It is up to you to ensure that exceptions are handled so that the methods are restored at the proper time.
Input:
Package to replace.
Reference to package that contains the wanted function (optional - defaults to caller's package)
List of functions to replace. Each function will be renamed to SUPER_$func so that the overridden function will work
Input:
Package that is overridden
Reference to package that contains the wanted function (optional - defaults to caller's package)
Darin McBride, <dmcbride at cpan.org>
Please report any bugs or feature requests to bug-module-replace at rt.cpan.org, or through
the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Module-Replace. I will be notified, and then you'll
automatically be notified of progress on your bug as I make changes.
You can find documentation for this module with the perldoc command.
perldoc Module::Replace
You can also look for information at:
Copyright 2008 Darin McBride, all rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
| Module-Replace documentation | Contained in the Module-Replace distribution. |
package Module::Replace; use warnings; use strict; #use 5.010;
our $VERSION = '0.02';
sub import { my $self = shift; my $class = shift; my ($caller) = caller(0); return 1 unless $class; # first, load the module, and make the caller derived from it. # 'base' does a lot of work - let's abuse that. eval qq[ package $caller; use base '$class'; ]; die $@ if $@; replace($class, \$caller, @_) if @_; 1; }
my %overrides; sub replace { my $class = shift; my ($caller) = ref $_[0] && ref $_[0] eq 'SCALAR' ? ${shift()} : caller(0); # now, replace desired methods. for my $func (@_) { no strict 'refs'; no warnings; local ($^W) = 0; # in case "-w" is used *{"${class}::SUPER_$func"} = \&{"${class}::$func"} if ${"${class}::"}{$func}; *{"${class}::$func"} = \&{"${caller}::$func"}; # keep track of what was overridden for reversals. $overrides{$caller}{$class}{$func}++; } }
sub restore { my $class = shift; my ($caller) = ref $_[0] && ref $_[0] eq 'SCALAR' ? ${shift()} : caller(0); for my $func (keys %{$overrides{$caller}{$class}}) { no strict 'refs'; no warnings; local ($^W) = 0; # in case "-w" is used if (exists ${"${class}::"}{"SUPER_$func"}) { *{"${class}::$func"} = \&{"${class}::SUPER_$func"}; delete ${"${class}::"}{"SUPER_$func"}; } else { delete ${"${class}::"}{$func}; } } }
1; # End of Module::Replace