Hack 30. Reload Modified Modules
Update modules in a running program without restarting.
Developing a long-running program can be a
Perl can do that too. The HackAll it takes is a simple module named Module::Reloader :
package Module::Reloader;
use strict;
use warnings;
my %module_times;
INIT
{
while (my ($module, $path) = each %INC)
{
$module_times{ $module } = -M $path;
}
}
sub reload
{
while (my ($module, $time) = each %module_times)
{
my $mod_time = -M $INC{$module};
next if $time = = $mod_time;
no warnings 'redefine';
require ( delete $INC{ $module } );
$module_times{ $module } = $mod_time;
}
}
1;
At the end of compile time [Hack #70], the module caches the
Running the HackUse the module as usual. Then, when you want to reload any loaded modules, call Module::Reloader::reload( ) . In a long-running server process, such as a pure-Perl web server running in development mode for a framework, this is easy to do right before processing a new incoming request.
Provided that the modules being modified don't keep around any weird state between
Hacking the Hack
The module as written
does
attempt to avoid
Changing the definition of classes while you have active instances of those classes can do scary things. It may be worthwhile to exclude certain modules, perhaps by specifying filters for modules to include or to exclude. This module currently does not erase the symbol tables of reloaded modules; that may be useful in certain circumstances. (It may be hazardous in others, where multiple modules affect symbols in a given package.) |
Hack 31. Create Personal Module Bundles
Create a personal bundle of your favorite modules. It never fails. I'm working on a new computer, a friend's computer, or a work computer and I've installed my favorite modules and written some code. use My::Favorite::Module; My::Favorite::Module->washes_the_dishes( ); Then I run the program. Can't locate My/Favorite/Module.pm in @INC (@INC contains ...
I did it again. I
That's where personal bundles come in. The Hack
A personal bundle is very easy to make. Just create a normal CPAN distribution. You don't even need to write tests for it: the modules you list will (hopefully) test
Instead, create an empty package with the modules you want listed in your POD contents section [Hack #32]. For example, suppose that you're a testing fanatic. You want to install your favorite testing modules, so you decide to call your bundle Bundle::Personal:: Mine (where Mine is your PAUSE ID). package Bundle::Personal::Mine; $VERSION = '0.42'; 1; __END__ =head1 NAME Bundle::Personal::Mine - My favorite testing modules =head1 SYNOPSIS perl -MCPAN -e 'install Bundle::Personal::Mine' =head1 CONTENTS Test::Class Test::Differences Test::Exception Test::MockModule Test::Pod Test::Pod::Coverage Test::WWW::Mechanize =head1 DESCRIPTION My favorite modules. ... rest of POD, if any ... Then just package up your tarball and stow it in a safe place (or even upload it to the CPAN). Running the HackFrom then on, to install all of your favorite modules, just type cpanp i Bundle::Personal::Mine for CPANPLUS, perl -MCPAN -e 'install Bundle::Personal::Mine' for CPAN , or whatever your favorite module installation incantation is. Hacking the Hack
When preparing a personal bundle, be selective about what you include. If you include a module that routinely fails tests, the entire bundle installation might fail. If that happens, try to install the
Other uses for such bundles include software development kits, corporate bundles, and application support modules. The CPAN already has bundles for Bundle::Test , Bundle::BioPerl , Bundle::MiniVend , and so on. Go to your favorite CPAN mirror and search for bundles. The bundle you want to create may already exist.
|