The new implementation is called "ReRequire" and simply deletes a given module name from %INC and re-requires it (hence the name). This essentially means that modules that are written to be re-requirable are code compartments that allow the re-definition of constants at compile and run time.
Here is a quick example of Package::ReRequire in use.
Package::ToBeReRequired
package Package::ToBeReRequired1;
use strict;
use Carp();
use Package::ReRequire(
CLUCK => 0,
METHOD => 0,
CONDITION => 0,
THING => 'default_thing',
);
sub get_sub {
use warnings;
return sub {
my( $self ) = @_ if METHOD;
my( $output ) = ( METHOD ) ? $self : '';
if( CONDITION ) {
$output .= ' CONDITION ';
};
$output .= ' UNCONDITIONAL ';
$output .= THING;
Carp::cluck __CALLER__ . ' clucking ' if CLUCK;
return $output;
};
}
1;
__END__
Package::ReRequire1
package Package::ReRequire1;
use strict;
use warnings;
# use Data::Dumper; $Data::Dumper::Terse=1;
use Package::ReRequire();
sub import {
Package::ReRequire::rerequire(
'Package::ToBeReRequired1',
CLUCK => 0,
METHOD => 0,
CONDITION => 1,
THING => __PACKAGE__,
);
*function = Package::ToBeReRequired1::get_sub();
}
1;
__END__
Package::ReRequire2
package Package::ReRequire2;
use strict;
use warnings;
# use Data::Dumper; $Data::Dumper::Terse=1;
use Package qw[ReRequire];
sub import {
ReRequire::rerequire(
'Package::ToBeReRequired1',
CLUCK => 1,
METHOD => 1,
CONDITION => 0,
THING => __PACKAGE__,
);
*method = Package::ToBeReRequired1::get_sub();
}
1;
__END__
Then, you can do something like this to see what this is turned into:
$ perl -Mwarnings -e ' use B::Deparse; use Package::ReRequire1; print
+f( "%s = %s\n", $_, B::Deparse->new->coderef2text( \&{ "Package::ReRe
+quire1::" . $_ } ) ) for keys %{ "Package::ReRequire1::" };'
function = {
package Package::ToBeReRequired1;
BEGIN {${^WARNING_BITS} = "UUUUUUUUUUUU"}
use strict 'refs';
'???';
my($output) = '';
do {
$output .= ' CONDITION '
};
$output .= ' UNCONDITIONAL ';
$output .= 'Package::ReRequire1';
'???';
return $output;
}
BEGIN = ;
import = {
package Package::ReRequire1;
BEGIN {${^WARNING_BITS} = "UUUUUUUUUUUU"}
use strict 'refs';
Package::ReRequire::rerequire('Package::ToBeReRequired1', 'CLUCK',
+ 0, 'METHOD', 0, 'CONDITION', 1, 'THING', 'Package::ReRequire1');
*function = Package::ToBeReRequired1::get_sub();
}
$ perl -Mwarnings -e ' use B::Deparse; use Package::ReRequire2; print
+f( "%s = %s\n", $_, B::Deparse->new->coderef2text( \&{ "Package::ReRe
+quire2::" . $_ } ) ) for keys %{ "Package::ReRequire2::" };'
BEGIN = ;
method = {
package Package::ToBeReRequired1;
BEGIN {${^WARNING_BITS} = "UUUUUUUUUUUU"}
use strict 'refs';
my($self) = @_;
my($output) = $self;
'???';
$output .= ' UNCONDITIONAL ';
$output .= 'Package::ReRequire2';
Carp::cluck('Package::ReRequire2 clucking ');
return $output;
}
import = {
package Package::ReRequire2;
BEGIN {${^WARNING_BITS} = "UUUUUUUUUUUU"}
use strict 'refs';
ReRequire::rerequire('Package::ToBeReRequired1', 'CLUCK', 1, 'METH
+OD', 1, 'CONDITION', 0, 'THING', 'Package::ReRequire2');
*method = Package::ToBeReRequired1::get_sub();
}
To download the code and see the full test suite, check out:
$ export CVSROOT=:pserver:anon@bennymack.com:/home/ben/documents/cvsro
+ot
$ cvs co my_modules
Creative name, I know! Ok, that's all for now. Let me know what you think. The interface is certainly not finalized. It's just the first thing I settled on that looks usable. All suggestions will be considered. Patches welcome. Thanks!