I'm currently experimenting with reloading a module. The aim I'm hoping to achieve is to be able to change something in the defined subroutine in the module file, and then reload that module, using the new definitions.
Currently, I am changing the print statement in the test
subroutine to print "this is some different text" after waiting for the subroutine to execute the original code, and before the module is reloaded.
However, what I'm currently getting is the message:Subroutine test redefined at /Test/testmodule.pm line 9.
This is exactly what I want, but the output is as follows.
this is some text Subroutine test redefined at /Test/testmodule.pm line 9. this is some text
What I'm hoping is that when the module is reloaded, and it realises that the subroutine has been redefined, is that next time it executes the test subroutine, it will refer to the new definition rather than the old one.
I've searched through previous questions on reloading modules, but the answers given were things like looping dependencies (package A uses B, and B uses A), or namespace collision in packages, but this is not the issue at hand here. I want the subroutine to be redefined, and the new definition used.
source code: main.pl
#!/usr/bin/perl
use strict;
use warnings;
use Module::Reload::Selective;
use Test::testmodule;
while(1) {
test(); #run module's define subroutine
sleep(5); #stop terminal from being flooded too quickly
#Ensure that the module is reloaded
$Module::Reload::Selective::Options->{SearchProgramDir} = 1;
$Module::Reload::Selective::Options->{ReloadOnlyIfEnvVarsSet} = 0;
Module::Reload::Selective->reload(qw(Test::testmodule)); #reload!
}
source code: testmodule.pm (in ./Test/
relative to main.pl)
#!/usr/bin/perl
use strict;
use warnings;
# allow exportation
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(test);
sub test {
print("this is some text\n"); # this line is edited in the source file to
# 'print("this is some different text\n");'
}
1;
Any pointers or references to tutorials would be brilliant. In fact, if the answer isn't incredibly simple, not telling me the answer directly will allow me to read your suggested material and gain an overall better understanding.
All required CPAN modules have been installed, and I can confirm that the testmodule.pm is being successfully written after changing.
OS: Scientific Linux CERN 6, kernel version 2.6.32-131.4.1.el6.x86_64
Perl: v5.10.1 (*) built for x86_64-linux-thread-multi
Many thanks in advance,
Owen.
I don't know if this is the problem or not yet, but you are missing your package
statement in the module. This means test
is main::test
not Test::testmodule::test
.
Yep, it was a combination of cjm's answer and mine. This code works for me:
In Test/testmodule.pm
:
package Test::testmodule;
use strict;
use warnings;
# allow exportation
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(test);
sub test {
print "this is some text, counter 1\n";
}
1;
In main.pl
:
#!/usr/bin/perl
use strict;
use warnings;
use Module::Reload::Selective;
use Test::testmodule;
while(1) {
test(); #run module's define subroutine
my $module = do {
open my $fh, "<", "Test/testmodule.pm"
or die "could not open the module: $!";
local $/;
<$fh>;
};
$module =~ s/counter ([0-9])/"counter " . ($1 + 1)/e;
open my $fh, ">", "Test/testmodule.pm"
or die "could not open the module: $!";
print $fh $module;
close $fh;
#Ensure that the module is reloaded
$Module::Reload::Selective::Options->{SearchProgramDir} = 1;
$Module::Reload::Selective::Options->{ReloadOnlyIfEnvVarsSet} = 0;
Module::Reload::Selective->reload(qw(Test::testmodule));
Test::testmodule->import;
} continue {
sleep 1;
}
To clarify, Perl 5 does not create a namespace when you create a .pm
file. It creates a namespace when you say package NamespaceName
or you reference that namespace like this
sub Test::testmodule::test {
print "this is some text, counter 1\n";
}
Since the test
function in your version was not in a the Test::testmodule
namespace, it never got reloaded.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With